{"record":{"id":"a53ade7eb38afa46","repo":"microsoft/aspire","slug":"aspiredict-must-be-resolved-before-it-can-be-serialized","errorCode":null,"errorMessage":"AspireDict must be resolved before it can be serialized directly. Pass it to generated SDK methods instead of calling JSON.stringify directly.","messagePattern":"AspireDict must be resolved before it can be serialized directly\\. Pass it to generated SDK methods instead of calling JSON\\.stringify directly\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/Aspire.Hosting.CodeGeneration.TypeScript/Resources/base.mts","lineNumber":997,"sourceCode":"    /**\n     * Converts the dictionary to a plain object (creates a copy).\n     * Only works when K is string.\n     */\n    async toObject(): Promise<Record<string, V>> {\n        const handle = await this._ensureHandle();\n        return await this._client.invokeCapability('Aspire.Hosting/Dict.toObject', {\n            dict: handle\n        }) as Record<string, V>;\n    }\n\n    async toTransportValue(): Promise<MarshalledHandle> {\n        const handle = await this._ensureHandle();\n        return handle.toJSON();\n    }\n\n    toJSON(): MarshalledHandle {\n        if (!this._resolvedHandle) {\n            throw new Error(\n                'AspireDict must be resolved before it can be serialized directly. ' +\n                'Pass it to generated SDK methods instead of calling JSON.stringify directly.'\n            );\n        }\n\n        return this._resolvedHandle.toJSON();\n    }\n}\n\nexport const AspireDict = AspireDictImpl;\n","sourceCodeStart":979,"sourceCodeEnd":1008,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Hosting.CodeGeneration.TypeScript/Resources/base.mts#L979-L1008","documentation":"AspireDict.toJSON() refuses to serialize a dict whose handle has not been resolved yet. Dicts are marshalled through the app host, and only after resolution do they have a wire representation. Calling JSON.stringify on an unresolved AspireDict triggers this error.","triggerScenarios":"Calling JSON.stringify(dict) on a new AspireDict; stringifying an object graph that contains an unresolved AspireDict; using the dict in a context that calls toJSON synchronously before the async resolution ran.","commonSituations":"Logging or persisting builder values before app start; sending dict-containing payloads to non-SDK HTTP endpoints; tests snapshotting unresolved dictionaries.","solutions":["Pass the AspireDict into the generated SDK method that consumes it, letting the library resolve it.","Await resolution (ensure-handle / toResolvedJSON path) before serializing.","For logs, stringify only resolved/plain values.","If you need raw JSON for external use, build a plain object instead of an AspireDict."],"exampleFix":"// before\nfs.writeFileSync(\"cfg.json\", JSON.stringify(myDict)); // unresolved\n\n// after\nconst resolved = await myDict.toJSON();\nfs.writeFileSync(\"cfg.json\", JSON.stringify(resolved));","handlingStrategy":"validation","validationCode":"const resolved = await myDict.toJSON(); // resolve handle first\nconst json = JSON.stringify(resolved);","typeGuard":"function isUnresolvedAspireValue(v: unknown): boolean {\n  return v !== null && typeof v === \"object\" && \"_resolvedHandle\" in v && (v as { _resolvedHandle?: unknown })._resolvedHandle === undefined;\n}","tryCatchPattern":"try {\n  persist(JSON.stringify(cfg));\n} catch (e) {\n  if (e instanceof Error && e.message.includes(\"AspireDict must be resolved\")) {\n    persist(JSON.stringify(await toResolved(cfg)));\n  } else throw e;\n}","preventionTips":["Consume AspireDict via generated SDK methods only.","Await handle resolution before serializing or snapshotting.","Build plain objects when raw JSON is required for external systems."],"tags":["serialization","typescript","async","unresolved-state"],"backgroundTag":"json-serialization-failed","analyzedSha":"25830f84bd145686607ad00c057b3f84e2e51d43","analyzedAt":"2026-09-16T11:10:06.193Z","contentChangedAt":"2026-09-16T11:10:06.193Z","schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}