acoustic-carpenter-78188
02/13/2026, 10:35 PMlookup_image_in_cache where images created with Image.from_ref_name() would incorrectly fall back to image.uri when no cache existed or when there were no layers. This could cause issues because ref_name images need to be resolved from the image cache.
Changes:
• Added image._ref_name is None check before returning image.uri early
• Images with a ref_name now always go through proper cache lookup
• If ref_name image is not found in cache, raises RuntimeUserError as expected
## Test Plan
Before:
[Screenshot 2026-02-13 at 2 36 20 PM](https://private-user-images.githubusercontent.com/37936015/549702703-65e3ff87-1e27-4625-a3fd-bd8040a26c85.png?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NzEzNTgwNjQsIm5iZiI6MTc3MTM1Nzc2NCwicGF0aCI6Ii8zNzkzNjAxNS81NDk3MDI3MDMtNjVlM2ZmODctMWUyNy00NjI1LWEzZmQtYmQ4MDQwYTI2Yzg1LnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNjAyMTclMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjYwMjE3VDE5NDkyNFomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWE3NTNkZjVkNGExMTIwMTRiMmJkNGU4NDhlZjgyNmYzMzIzZmYwODE3NWFjNGE3Yzg2ZDA0YzFiYmNiMjI2M2ImWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.vSoiGeTOnv78HkPervKUGidoryRTUrtkNJ4PmxqJfY4)
After:
[Screenshot 2026-02-13 at 2 36 31 PM](https://private-user-images.githubusercontent.com/37936015/549702783-61c66cc4-8589-4dc6-bf56-77b77cfd7e0d.png?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NzEzNTgwNjQsIm5iZiI6MTc3MTM1Nzc2NCwicGF0aCI6Ii8zNzkzNjAxNS81NDk3MDI3ODMtNjFjNjZjYzQtODU4OS00ZGM2LWJmNTYtNzdiNzdjZmQ3ZTBkLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNjAyMTclMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjYwMjE3VDE5NDkyNFomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTUxMTUwMDc1ZTNkNjIyY2MwNmE3ZGUwMzFkNjFhOTUzMTBiOGI3NDNjOTE1ZmM1OTkxNWNmZjJmMGE0YTdhNTgmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.NYdg8ZMq-bzNPxPBGajqV1CNYxaUFVsSkXL40aU9PYY)
import asyncio
import typing
from pathlib import Path
import ray
from kubernetes.client import V1PodSpec, V1Container, V1ResourceRequirements
from flyteplugins.ray.task import HeadNodeConfig, RayJobConfig, WorkerNodeConfig
import flyte.remote
import flyte.storage
@ray.remote
def f(x):
return x * x
ray_config = RayJobConfig(
head_node_config=HeadNodeConfig(
ray_start_params={"log-color": "True"},
pod_template=flyte.PodTemplate(
pod_spec=V1PodSpec(
containers=[
V1Container(
name="ray-worker",
resources=V1ResourceRequirements(
limits={"cpu": f"2000m"},
requests={"cpu": f"2000m"},
),
)
],
)
),
),
worker_node_config=[WorkerNodeConfig(group_name="ray-group", replicas=2)],
runtime_env={"pip": ["numpy", "pandas"]},
enable_autoscaling=False,
shutdown_after_job_finishes=True,
ttl_seconds_after_finished=300,
)
# image = (
# flyte.Image.from_debian_base()
# .with_apt_packages("wget")
# .with_pip_packages("ray[default]==2.46.0", "pip", "flyteplugins-ray", "kubernetes").with_local_v2()
# )
image = flyte.Image.from_ref_name("base_image")
ray_env = flyte.TaskEnvironment(
name="ray_env",
plugin_config=ray_config,
image=image,
resources=flyte.Resources(cpu=(1, 2), memory=("4000Mi", "8000Mi")),
)
task_env = flyte.TaskEnvironment(
name="hello_ray", resources=flyte.Resources(cpu=(1, 2), memory=("400Mi", "1000Mi")), image=image,
# depends_on=[ray_env],
)
@task_env.task()
async def hello_ray():
await asyncio.sleep(20)
print("Hello from the Ray task!")
@ray_env.task
async def hello_ray_nested(n: int = 3) -> typing.List[int]:
print("running ray task")
t = asyncio.create_task(hello_ray())
futures = [f.remote(i) for i in range(n)]
res = ray.get(futures)
await t
return res
@task_env.task()
async def hello_wf():
await hello_ray_nested()
if name == "__main__":
flyte.init_from_config(images=("base_image=356633062068.dkr.ecr.us-east-2.amazonaws.com/union/demo:flyte-babd547dbd23b96c91b1e8feb9daf0b1",))
run = flyte.with_runcontext(env_vars={"LOG_LEVEL": "10"}).run(hello_wf)
print("run name:", run.name)
print("run url:", run.url)
run.wait(run)
action_details = flyte.remote.ActionDetails.get(run_name=run.name, name="a0")
for log in action_details.pb2.attempts[-1].log_info:
print(f"{log.name}: {log.uri}")
flyteorg/flyte-sdkacoustic-carpenter-78188
02/17/2026, 7:49 PM