langgenius / langgenius/dify

Agent image icon fails to load (404): AppIcon receives the raw file id instead of icon_url

Open Beginner friendly
#40,442 1 comment 1 reaction 0 assignees View on GitHub
Dominant language
TypeScript
Stars
156k
Forks
24.7k
Avg merge
21h 41m
Merged PRs (30d)
600

Description

### Self Checks

- [x] I have read the [Contributing Guide](https://github.com/langgenius/dify/blob/main/CONTRIBUTING.md) and [Language Policy](https://github.com/langgenius/dify/issues/1542).
- [x] This is only for bug report, if you would like to ask a question, please head to [Discussions](https://github.com/langgenius/dify/discussions/categories/general).
- [x] I have searched for existing issues [search for existing issues](https://github.com/langgenius/dify/issues), including closed ones.
- [x] I confirm that I am using English to submit this report, otherwise it will be closed.
- [x] 【中文用户 & Non English User】请使用英语提交,否则会被关闭 :)
- [x] Please do not modify this template :) and fill in all the required fields.

### Dify version

1.16.1

### Cloud or Self Hosted

Self Hosted (Docker)

### Steps to reproduce

1. Enable Agent v2 (`ENABLE_AGENT_V2=true`) and create an Agent, e.g. `Test-agent`.
2. Set the Agent icon to an uploaded **image** (not an emoji). The upload itself succeeds: `POST /console/api/files/upload` returns 200 and a row is created in `upload_files`.
3. Reload the page and look at the Agent icon on the Agents list, or on the Agent configure page.

Requests observed in the browser devtools and in the nginx access log:

```
GET /29bdb007-4d8c-4888-83a2-7587abcafb26 404
GET /agents/019fd69e-7b20-79ee-8e15-b289e27928bc/29bdb007-4d8c-4888-83a2-7587abcafb26 404
```

The requested path is the **bare `upload_files.id`**. Because it is not an absolute path, the browser resolves it relative to the current page, which is why the same id produces a different (and always wrong) URL on `/agents` versus `/agents//configure`.

Agents whose icon is an **emoji** are not affected. Apps, datasets and the webapp site icon are not affected either — only Agent icons of type `image`.

### ✔️ Expected Behavior

The Agent icon renders using the signed preview URL that the backend already computes and returns as `icon_url`, e.g.

```
/files/29bdb007-4d8c-4888-83a2-7587abcafb26/file-preview?timestamp=...&nonce=...&sign=...
```

### ❌ Actual Behavior

A 404 and a broken image placeholder, everywhere an Agent icon of type `image` is rendered.

### Root cause

The backend is fine. `AgentAppDetailWithSite` and `AgentAppPartial` both inherit the `icon_url` computed field from `AppDetailWithSite`, and it resolves correctly. Verified in a 1.16.1 container:

```python
>>> AgentAppDetailWithSite.model_validate(app_model, from_attributes=True, ...).model_dump(mode="json")["icon_url"]
'/files/29bdb007-4d8c-4888-83a2-7587abcafb26/file-preview?timestamp=1786355545&nonce=...&sign=...'
```

The problem is on the web side. `AppIcon` uses the `imageUrl` prop directly as the `` source:

```tsx
// web/app/components/base/app-icon/index.tsx
112: const isValidImageIcon = iconType === 'image' && imageUrl
138: app icon
```

But the Agent components pass `agent.icon` — the raw `upload_files` id — into `imageUrl`, where every other caller passes `icon_url`:

```tsx
// web/app/components/workflow/block-selector/agent-selector.tsx:230
imageUrl={agent.icon ?? undefined}

// web/app/components/workflow/nodes/agent-v2/components/agent-roster-field.tsx:73
imageUrl={agent.icon ?? undefined}
```

Compare with the correct pattern used elsewhere, e.g. app / dataset / site icons:

```tsx
imageUrl={app.icon_url}
```

The same `imageUrl: X.icon` pattern also appears in the shipped `dify-web:1.16.1` bundle in the Agent configure page header component (the chunk containing `i-custom-vender-agent-v2-configure`), so there is likely a third call site besides the two above. In the built output the bad pattern occurs only in Agent-related chunks:

```
$ grep -oE "imageUrl:[A-Za-z_$]+\.icon(\?\?|,|\}|\))" .js
# matches only in the agent header and block-selector chunks;
# all app/dataset/site chunks use imageUrl:X.icon_url
```

### Suggested fix

Pass `icon_url` instead of `icon` in the Agent call sites, falling back to `undefined`:

```diff
- imageUrl={agent.icon ?? undefined}
+ imageUrl={agent.icon_url ?? undefined}
```

`icon_url` is already present on both the Agent detail and the Agent list (roster) responses, so no backend change is needed.

Possibly related: #39447 (closed, reported against 1.16.0).

Contributor guide

Open the contributing guide

Research direction

Start in web/app/components/workflow/block-selector/agent-selector.tsx and web/app/components/workflow/nodes/agent-v2/components/agent-roster-field.tsx, then locate the additional Agent configure-page call site in the built bundle or its source. Compare these uses with app, dataset, and site icon callers, and verify that every Agent image icon renders from icon_url and no longer requests the raw upload file id.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
frontend
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
78/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.