{"record":{"id":"54797857274bdc16","repo":"vercel/ai","slug":"invalid-argument-for-parameter-requests-requests","errorCode":null,"errorMessage":"Invalid argument for parameter requests: requests must not be empty","messagePattern":"Invalid argument for parameter requests: requests must not be empty","errorType":"validation","errorClass":"InvalidArgumentError","httpStatus":null,"severity":"error","filePath":"packages/ai/src/batch/batch.ts","lineNumber":246,"sourceCode":"  }\n\n  return model;\n}\n\nfunction isBatchLanguageModel(\n  model: LanguageModelV4,\n): model is BatchLanguageModelV4 {\n  const candidate = model as Partial<BatchLanguageModelV4>;\n  return (\n    typeof candidate.experimental_doStartBatch === 'function' &&\n    typeof candidate.experimental_doGetBatchStatus === 'function' &&\n    typeof candidate.experimental_doGetBatchResults === 'function'\n  );\n}\n\nfunction validateRequests(requests: ReadonlyArray<TextBatchRequest>) {\n  if (requests.length === 0) {\n    throw new InvalidArgumentError({\n      parameter: 'requests',\n      value: requests,\n      message: 'requests must not be empty',\n    });\n  }\n\n  const ids = new Set<string>();\n\n  for (const request of requests) {\n    if (request.id.trim().length === 0) {\n      throw new InvalidArgumentError({\n        parameter: 'requests',\n        value: requests,\n        message: 'request IDs must not be empty',\n      });\n    }\n\n    if (ids.has(request.id)) {","sourceCodeStart":228,"sourceCodeEnd":264,"githubUrl":"https://github.com/vercel/ai/blob/69428b1f8b037e4d118fb4853428d5c4e620493c/packages/ai/src/batch/batch.ts#L228-L264","documentation":"validateACPLifecycleCompatibility checks persisted ACP lifecycle state before it is adopted by createACPV1. The state records which harness id produced it; if that id differs from the harness id of the current instance, the state is not transferable between harnesses and is rejected. This prevents resuming state across incompatible harness implementations.","triggerScenarios":"Calling createACPV1 with lifecycleData whose harnessId differs from the current harness's id, e.g. passing lifecycle state captured by harness-acp v1 into a different harness package or a harness configured under a different id.","commonSituations":"Migrating sessions between harness packages (e.g. harness-acp to a future harness); reusing serialized lifecycle state from another agent runtime; a typo or changed harnessId string in config.","solutions":["Use lifecycle state that was produced by this exact harness (same harnessId).","Regenerate the session/lifecycle state with the current harness instead of resuming foreign state.","If migrating harnesses deliberately, re-run the session under the new harness from scratch; state is not portable."],"exampleFix":"// before\ncreateACPV1({ harnessId: 'acp-v1-claude', lifecycle: stateFromOtherHarness })\n\n// after\nconst state = await captureLifecycle({ harnessId: 'acp-v1-claude' });\ncreateACPV1({ harnessId: 'acp-v1-claude', lifecycle: state })","handlingStrategy":"validation","validationCode":"if (lifecycleData.harnessId !== harnessId) {\n  throw new Error(`Lifecycle state from ${lifecycleData.harnessId} cannot be resumed by ${harnessId}`);\n}","typeGuard":null,"tryCatchPattern":"try {\n  harness = createACPV1({ lifecycle: state });\n} catch (error) {\n  if (error instanceof Error && error.message.includes('was produced by harness')) {\n    // foreign lifecycle state: start a fresh session\n    harness = createACPV1({});\n  } else {\n    throw error;\n  }\n}","preventionTips":["Store lifecycle state together with the harnessId that produced it and only look it up by that key.","Never share serialized lifecycle state across harness packages.","Key persisted sessions by harnessId so mismatches are impossible."],"tags":["acp","lifecycle","identity-mismatch","session-resume"],"backgroundTag":"lifecycle-state-mismatch","analyzedSha":"69428b1f8b037e4d118fb4853428d5c4e620493c","analyzedAt":"2026-08-30T12:32:21.016Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}