{"record":{"id":"b17c66f6c4b4160a","repo":"can1357/oh-my-pi","slug":"no-session-local-unavailable","errorCode":null,"errorMessage":"No session - local:// unavailable","messagePattern":"No session - local:// unavailable","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/internal-urls/local-protocol.ts","lineNumber":487,"sourceCode":"\t\tconst fromContext = context?.localProtocolOptions;\n\t\tif (fromContext) return fromContext;\n\t\tconst override = LocalProtocolHandler.#override;\n\t\tif (override) return override;\n\t\tconst main = AgentRegistry.global()\n\t\t\t.list()\n\t\t\t.find(ref => ref.kind === \"main\");\n\t\tconst sessionManager = main?.session?.sessionManager;\n\t\tif (!sessionManager) return undefined;\n\t\treturn {\n\t\t\tgetArtifactsDir: () => sessionManager.getArtifactsDir(),\n\t\t\tgetSessionId: () => sessionManager.getSessionId(),\n\t\t};\n\t}\n\n\tasync resolve(url: InternalUrl, context?: ResolveContext): Promise<InternalResource> {\n\t\tconst opts = LocalProtocolHandler.resolveOptions(context);\n\t\tif (!opts) {\n\t\t\tthrow new Error(\"No session - local:// unavailable\");\n\t\t}\n\n\t\tconst resolved = await resolveLocalTarget(url, opts);\n\t\tif (resolved.kind === \"listing\") {\n\t\t\treturn buildListing(url, resolved.root);\n\t\t}\n\t\tif (resolved.kind === \"directory\") {\n\t\t\treturn buildDirectoryResource(url.href, resolved.path, [LOCAL_WRITE_NOTE]);\n\t\t}\n\n\t\treturn buildFileResource(url, resolved);\n\t}\n\n\tasync complete(_query?: string, context?: ResolveContext): Promise<UrlCompletion[]> {\n\t\tconst opts = LocalProtocolHandler.resolveOptions(context);\n\t\tif (!opts) return [];\n\t\tconst localRoot = path.resolve(resolveLocalRoot(opts));\n\t\ttry {","sourceCodeStart":469,"sourceCodeEnd":505,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/internal-urls/local-protocol.ts#L469-L505","documentation":"LocalProtocolHandler.resolve needs a LocalProtocolOptions (artifacts dir + session id providers) sourced from the call context, a process-global override, or a registered main session in AgentRegistry. If all three are absent there is no session-scoped local root to resolve against, so the handler throws this error rather than guessing a location.","triggerScenarios":"Calling router.resolve/read with a local:// URL before any agent session is created; SDK consumers that never wired localProtocolOptions (neither context.localProtocolOptions nor LocalProtocolHandler.setOverride) and have no AgentRegistry main session; tool invocations in worker processes where the registry was not populated.","commonSituations":"Standalone scripts embedding the SDK and resolving local:// URLs outside a session lifecycle; tests invoking the handler without registering a session; TUI/plugins running before session startup completes.","solutions":["Create/register an agent session (main kind) before resolving local:// URLs, or run the resolution inside an active session so the context carries localProtocolOptions.","For SDK embedders, call LocalProtocolHandler.setOverride({ getArtifactsDir, getSessionId }) with your own mapping.","Pass context: { localProtocolOptions } explicitly on the resolve/read call in multi-session hosts."],"exampleFix":"// before\nawait router.resolve(\"local://notes.md\"); // no session\n// after\nLocalProtocolHandler.setOverride({\n  getArtifactsDir: () => artifactsDir,\n  getSessionId: () => sessionId,\n});\nawait router.resolve(\"local://notes.md\");","handlingStrategy":"type-guard","validationCode":"import { LocalProtocolHandler } from './local-protocol';\nconst opts = LocalProtocolHandler.resolveOptions(context);\nif (!opts) throw new Error('No active session: cannot resolve local:// URLs');","typeGuard":"function hasLocalOptions(context) { return Boolean(context?.localProtocolOptions ?? LocalProtocolHandler.resolveOptions(context)); }","tryCatchPattern":"try { resource = await handler.resolve(url, ctx); } catch (e) { if (e.message === 'No session - local:// unavailable') { /* initialize/register a session or set an override before retrying */ } else throw e; }","preventionTips":["Check LocalProtocolHandler.resolveOptions(context) before exposing local:// URLs to users.","Register the main session in AgentRegistry before any tool resolution runs.","In SDK/embedded hosts, always install LocalProtocolHandler.setOverride with explicit providers."],"tags":["session","initialization","configuration"],"backgroundTag":"missing-session-context","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}