{"record":{"id":"7735d847dbd561e4","repo":"google-gemini/gemini-cli","slug":"task-taskid-is-missing-persisted-state-in-metad","errorCode":null,"errorMessage":"Task ${taskId} is missing persisted state in metadata.","messagePattern":"Task (.+?) is missing persisted state in metadata\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/a2a-server/src/persistence/gcs.ts","lineNumber":103,"sourceCode":"  }\n\n  private getObjectPath(taskId: string, type: ObjectType): string {\n    if (!isTaskIdValid(taskId)) {\n      throw new Error(`Invalid taskId: ${taskId}`);\n    }\n    return `tasks/${taskId}/${type}.tar.gz`;\n  }\n\n  async save(task: SDKTask): Promise<void> {\n    await this.ensureBucketInitialized();\n    const taskId = task.id;\n    const persistedState = getPersistedState(\n      // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion\n      task.metadata as PersistedTaskMetadata,\n    );\n\n    if (!persistedState) {\n      throw new Error(`Task ${taskId} is missing persisted state in metadata.`);\n    }\n    const workDir = process.cwd();\n\n    const metadataObjectPath = this.getObjectPath(taskId, 'metadata');\n    const workspaceObjectPath = this.getObjectPath(taskId, 'workspace');\n\n    const dataToStore = task.metadata;\n\n    try {\n      const jsonString = JSON.stringify(dataToStore);\n      const compressedMetadata = gzipSync(Buffer.from(jsonString));\n      const metadataFile = this.storage\n        .bucket(this.bucketName)\n        .file(metadataObjectPath);\n      await metadataFile.save(compressedMetadata, {\n        contentType: 'application/gzip',\n      });\n      logger.info(","sourceCodeStart":85,"sourceCodeEnd":121,"githubUrl":"https://github.com/google-gemini/gemini-cli/blob/5024443c7217464a66e98f80d73172a26440bd8f/packages/a2a-server/src/persistence/gcs.ts#L85-L121","documentation":"Thrown by GCSTaskStore.save() when the task being persisted has no valid __persistedState entry in its metadata. The persisted state (stored under the METADATA_KEY '__persistedState') must contain an _agentSettings object (with kind === 'state_agent_settings' and a string workspacePath) and a _taskState field. Without it, the GCS store has nothing durable to write.","triggerScenarios":"Calling store.save(task) where task.metadata lacks the '__persistedState' key, or where the nested _agentSettings or _taskState are missing/malformed. This occurs when a task is constructed manually instead of through the agent executor that calls setPersistedState().","commonSituations":"Manually building an SDK Task object without populating persisted state; migrating from an older metadata format that didn't use __persistedState; a bug in the executor (executor.ts) that skips the setPersistedState() call before delegating to save.","solutions":["Ensure the task metadata is populated via setPersistedState(metadata, { _agentSettings, _taskState }) before calling save.","Before calling save, verify getPersistedState(task.metadata) returns a non-undefined value.","Confirm _agentSettings has kind === 'state_agent_settings' and a string workspacePath, and _taskState is present."],"exampleFix":"// before\nconst task: SDKTask = { id, metadata: {}, ... };\nawait store.save(task); // throws\n\n// after\nimport { setPersistedState } from '../types.js';\nconst task: SDKTask = {\n  id,\n  metadata: setPersistedState({}, {\n    _agentSettings: { kind: 'state_agent_settings', workspacePath: '/work', ... },\n    _taskState: 'submitted',\n  }),\n  ...,\n};\nawait store.save(task);","handlingStrategy":"validation","validationCode":"import { getPersistedState } from '../types.js';\n\nfunction canSaveTask(task: SDKTask): boolean {\n  return getPersistedState(task.metadata as PersistedTaskMetadata) !== undefined;\n}\n\n// Before save:\nif (!canSaveTask(task)) {\n  task.metadata = setPersistedState(task.metadata, {\n    _agentSettings: agentSettings,\n    _taskState: currentState,\n  });\n}\nawait store.save(task);","typeGuard":"import { isPersistedStateMetadata, METADATA_KEY } from '../types.js';\n\nfunction hasValidPersistedState(metadata: unknown): boolean {\n  return (\n    typeof metadata === 'object' &&\n    metadata !== null &&\n    METADATA_KEY in metadata &&\n    isPersistedStateMetadata((metadata as Record<string, unknown>)[METADATA_KEY])\n  );\n}","tryCatchPattern":"try {\n  await store.save(task);\n} catch (e) {\n  if (e instanceof Error && e.message.includes('missing persisted state')) {\n    // Repopulate and retry, or log and skip\n    task.metadata = setPersistedState(task.metadata, state);\n    await store.save(task);\n  } else {\n    throw e;\n  }\n}","preventionTips":["Always create task metadata through the agent executor which calls setPersistedState().","Add a unit test asserting getPersistedState(task.metadata) is non-undefined before any save call.","Never construct a Task object with an empty or partial metadata object intended for persistence."],"tags":["persistence","gcs","a2a","metadata","state"],"backgroundTag":null,"analyzedSha":"5024443c7217464a66e98f80d73172a26440bd8f","analyzedAt":"2026-08-12T06:01:53.711Z","schemaVersion":2},"datasetVersion":"2026-08-12T12:31:55.035Z"}