You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
global project row icon_url permanently polluted — all workspaces display wrong icon #39488
The global row (id='global', worktree='/') in the project table acts as the fallback data source for all workspaces. Its icon_url field was found to contain a base64-encoded .ico file from a specific project directory. This causes every project in the sidebar to display the same cookie icon, overriding both default colored avatars and custom icons.
Plugins
None
OpenCode version
v1.17.8 (Desktop) and v1.17.8 (CLI)
Steps to reproduce
Have a project directory containing an img/icon.ico (or favicon.ico).
Open it in OpenCode Desktop.
Observe: after some interaction (possibly Edit Project or auto-discovery), the icon leaks into the global row.
All other projects now display this icon instead of their own.
Screenshot and/or share link
Operating System
Windows 10 Home (10.0.19045 Build 19045), Lenovo LAPTOP-CSJ6J9R1
The global row (id='global', worktree='/') in the project table acts as the fallback data source for all workspaces that lack their own icon metadata. Its icon_url field was found to contain a base64-encoded .ico file from a specific project directory (E:\04_archive\cookieclicker-gh-pages\img\icon.ico). This causes every project in the sidebar to display the same cookie icon, overriding both default colored avatars and custom icons set via Edit Project.
Reproduction
Have a project directory containing an img/icon.ico (or icon.png, favicon.ico)
Open it in OpenCode Desktop
Observe: after some interaction (possibly Edit Project or auto-discovery), the icon leaks into the global row
All other projects now display this icon instead of their own
Root Cause Analysis
Data flow: getProjectAvatarSource() in packages/app/src/pages/layout/helpers.ts:96-102 resolves icons with this priority:
if(icon?.override)returnicon.override// from workspace:icon (electron-store)if(icon?.color)returnundefined// falls back to colored avatarreturnicon?.url// from project.icon_url (SQLite) ← POLLUTED
When no specific project has icon_color or icon_url_override set, the rendering falls through to the project table's icon_url. The global row serves as catch-all — so its icon_url affects every project without explicit icon data.
Pre-fix DB state:
SELECT id, worktree, icon_url, icon_color FROM project WHERE id='global';
-- global | / | data:image/vnd.microsoft.icon;base64,AAABAAEAEBAQAAAAAA... | NULL
How global got polluted: The exact entry point is likely icon auto-detection. When OpenCode discovers icon files in project directories and stores them to the project table, a path mismatch (e.g., zero-width space in 04_archive\u200B\cookieclicker-gh-pages) could cause the icon to be written against the global fallback row instead of a project-specific row.
Secondary Bug: Edit Project Save Path
Verified from source and local data: the save.mutationFn() in packages/app/src/components/edit-project.ts:71-95 has two code paths:
if(props.project.id&&props.project.id!=="global"){// Path A: Writes to project table + workspace:icon (sidebars reads BOTH)awaitserverCtx().sdk.client.project.update({...});serverCtx().sync.project.icon(worktree,iconOverride);}else{// Path B: Writes ONLY to workspace:project (sidebar NEVER reads this for icons)serverCtx().sync.project.meta(worktree,{name,icon: {color, override}});}
The sidebar reads childStore.icon (workspace:icon key) and project.icon_url (SQLite table), but Path B writes to workspace:project — making any Edit Project save on local projects silently lost.
Confirmed locally: workspace files contain workspace:project entries with icon data, but the rendering code never reads from this key for icon display.
Notice: no project has icon_url or icon_url_override set. Only icon_color is populated. The global row's icon_url is the sole source of the cookie icon appearing everywhere.
Local Fix Applied
UPDATE project SET icon_url =NULLWHERE id ='global';
All projects immediately show their correct colored avatars after restart.
Workaround for Affected Users
-- 1. Close OpenCode Desktop-- 2. Open opencode.db with sqlite3:
sqlite3 "%USERPROFILE%\.local\share\opencode\opencode.db"-- 3. Run:UPDATE project SET icon_url =NULLWHERE id ='global';
-- 4. Restart OpenCode Desktop
Proposed Code-Level Fixes
Guard global row: Add assertion in any icon-writing code path: if (projectId === "global") return — the global row should NEVER receive a project-specific icon URL
Add fallback in enrich(): layout.tsx:224 should also check childStore.projectMeta?.icon?.override as a fallback for projects without workspace:icon entries
Data migration: On app startup, sanitize: UPDATE project SET icon_url = NULL WHERE id = 'global' AND icon_url IS NOT NULL
Unify save path: edit-project.ts should call both project.icon() and project.meta() regardless of project ID
Confirming this on the latest desktop release (v1.18.13, macOS) — still reproducible.
Empirical data from my machine:
The project table in ~/.local/share/opencode/opencode.db has a row with id='global' / worktree='/' holding a polluted icon_url (base64 data URL).
The stored bytes are byte-for-byte identical to my project's frontend/public/favicon.ico (456 bytes). So the favicon auto-discovery (the desktop app always sets OPENCODE_EXPERIMENTAL_ICON_DISCOVERY=true for its bundled server) wrote the discovered icon into the global fallback row instead of the project's own row.
25+ sessions on my machine have project_id='global', so every project/session that resolves to the global row renders that same favicon — every project in the sidebar shows the same photo.
The originating project itself displays correctly because it also has icon_color set (color wins over url in getProjectAvatarSource), which makes the leak look exactly like "one project's photo applied to all others".
Workaround that works (after quitting the desktop app):
UPDATE project SET icon_url =NULL, icon_url_override =NULLWHERE id ='global';
Purely cosmetic, but it affects every workspace and is quite confusing. Happy to provide more logs/screenshots if helpful.
Activity
Jasper-111 commentedon Jul 29, 2026
Title: [BUG]
globalproject rowicon_urlpermanently polluted — all workspaces display wrong iconEnvironment
@opencode-aidesktopat%LOCALAPPDATA%\Programs\)%USERPROFILE%\.local\share\opencode\opencode.db(SQLite)%APPDATA%\ai.opencode.desktop\opencode.workspace.*.dat(electron-store JSON)Summary
The
globalrow (id='global',worktree='/') in theprojecttable acts as the fallback data source for all workspaces that lack their own icon metadata. Itsicon_urlfield was found to contain a base64-encoded.icofile from a specific project directory (E:\04_archive\cookieclicker-gh-pages\img\icon.ico). This causes every project in the sidebar to display the same cookie icon, overriding both default colored avatars and custom icons set via Edit Project.Reproduction
img/icon.ico(oricon.png,favicon.ico)globalrowRoot Cause Analysis
Data flow:
getProjectAvatarSource()inpackages/app/src/pages/layout/helpers.ts:96-102resolves icons with this priority:When no specific project has
icon_colororicon_url_overrideset, the rendering falls through to theprojecttable'sicon_url. Theglobalrow serves as catch-all — so itsicon_urlaffects every project without explicit icon data.Pre-fix DB state:
How
globalgot polluted: The exact entry point is likely icon auto-detection. When OpenCode discovers icon files in project directories and stores them to theprojecttable, a path mismatch (e.g., zero-width space in04_archive\u200B\cookieclicker-gh-pages) could cause the icon to be written against theglobalfallback row instead of a project-specific row.Secondary Bug: Edit Project Save Path
Verified from source and local data: the
save.mutationFn()inpackages/app/src/components/edit-project.ts:71-95has two code paths:The sidebar reads
childStore.icon(workspace:iconkey) andproject.icon_url(SQLite table), but Path B writes toworkspace:project— making any Edit Project save on local projects silently lost.Confirmed locally: workspace files contain
workspace:projectentries with icon data, but the rendering code never reads from this key for icon display.Database State (12 projects, all affected)
Notice: no project has
icon_urloricon_url_overrideset. Onlyicon_coloris populated. Theglobalrow'sicon_urlis the sole source of the cookie icon appearing everywhere.Local Fix Applied
All projects immediately show their correct colored avatars after restart.
Workaround for Affected Users
Proposed Code-Level Fixes
globalrow: Add assertion in any icon-writing code path:if (projectId === "global") return— the global row should NEVER receive a project-specific icon URLenrich():layout.tsx:224should also checkchildStore.projectMeta?.icon?.overrideas a fallback for projects withoutworkspace:iconentriesUPDATE project SET icon_url = NULL WHERE id = 'global' AND icon_url IS NOT NULLedit-project.tsshould call bothproject.icon()andproject.meta()regardless of project IDRelated
caleblea commentedon Aug 5, 2026
Confirming this on the latest desktop release (v1.18.13, macOS) — still reproducible.
Empirical data from my machine:
projecttable in~/.local/share/opencode/opencode.dbhas a row withid='global'/worktree='/'holding a pollutedicon_url(base64 data URL).frontend/public/favicon.ico(456 bytes). So the favicon auto-discovery (the desktop app always setsOPENCODE_EXPERIMENTAL_ICON_DISCOVERY=truefor its bundled server) wrote the discovered icon into theglobalfallback row instead of the project's own row.project_id='global', so every project/session that resolves to the global row renders that same favicon — every project in the sidebar shows the same photo.icon_colorset (color wins overurlingetProjectAvatarSource), which makes the leak look exactly like "one project's photo applied to all others".Workaround that works (after quitting the desktop app):
Purely cosmetic, but it affects every workspace and is quite confusing. Happy to provide more logs/screenshots if helpful.
github-actions commentedon Oct 4, 2026
To stay organized issues are automatically closed after 60 days of no activity. If the issue is still relevant please open a new one.