{"record":{"id":"b4671fb6550dbb5e","repo":"paperclipai/paperclip","slug":"modal-sandbox-environments-require-both-tokenid-an","errorCode":null,"errorMessage":"Modal sandbox environments require both tokenId and tokenSecret to be configured.","messagePattern":"Modal sandbox environments require both tokenId and tokenSecret to be configured\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/plugins/sandbox-providers/modal/src/plugin.ts","lineNumber":102,"sourceCode":"    cidrAllowlist: parseStringArray(raw.cidrAllowlist),\n    reuseLease: raw.reuseLease === true,\n  };\n}\n\nfunction isMultipleOf1000(value: number): boolean {\n  return value > 0 && value % 1000 === 0;\n}\n\nfunction resolveAuth(config: ModalDriverConfig): { tokenId: string; tokenSecret: string } | null {\n  // The plugin worker runs in a child process that does not inherit host env\n  // vars (see PluginWorkerManager.spawnProcess), so MODAL_TOKEN_ID /\n  // MODAL_TOKEN_SECRET cannot be read here. Credentials must come from the\n  // environment config, which Paperclip stores as company secrets.\n  const tokenId = config.tokenId ?? \"\";\n  const tokenSecret = config.tokenSecret ?? \"\";\n  if (!tokenId && !tokenSecret) return null;\n  if (!tokenId || !tokenSecret) {\n    throw new Error(\"Modal sandbox environments require both tokenId and tokenSecret to be configured.\");\n  }\n  return { tokenId, tokenSecret };\n}\n\nfunction createModalClient(config: ModalDriverConfig): ModalClient {\n  const auth = resolveAuth(config);\n  const params: ConstructorParameters<typeof ModalClient>[0] = {};\n  if (auth) {\n    params.tokenId = auth.tokenId;\n    params.tokenSecret = auth.tokenSecret;\n  }\n  if (config.environment) {\n    params.environment = config.environment;\n  }\n  return new ModalClient(params);\n}\n\nasync function resolveApp(client: ModalClient, config: ModalDriverConfig): Promise<App> {","sourceCodeStart":84,"sourceCodeEnd":120,"githubUrl":"https://github.com/paperclipai/paperclip/blob/a7e689b3c35347b529cb9f54c9b9a8575a3dcab6/packages/plugins/sandbox-providers/modal/src/plugin.ts#L84-L120","documentation":"Credential validation in resolveAuth for the Modal driver: one of tokenId/tokenSecret is missing from the environment config. Because the plugin worker child process does not inherit host env vars, MODAL_TOKEN_ID/MODAL_TOKEN_SECRET cannot be read there — both halves of the token pair must be stored in the environment config as company secrets.","triggerScenarios":"Thrown at packages/plugins/sandbox-providers/modal/src/plugin.ts:102 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Configure both tokenId and tokenSecret for Modal."],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"a7e689b3c35347b529cb9f54c9b9a8575a3dcab6","analyzedAt":"2026-08-18T22:49:45.177Z","contentChangedAt":"2026-08-18T22:49:45.177Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}