{"record":{"id":"ffbe5ec73674dbd3","repo":"can1357/oh-my-pi","slug":"omp-auth-broker-account-pool-file-entry-for-prov","errorCode":null,"errorMessage":"OMP_AUTH_BROKER_ACCOUNT_POOL_FILE entry for ${provider} must be an array of identity keys","messagePattern":"OMP_AUTH_BROKER_ACCOUNT_POOL_FILE entry for (.+?) must be an array of identity keys","errorType":"validation","errorClass":"AIError.ConfigurationError","httpStatus":null,"severity":"error","filePath":"packages/ai/src/auth-broker/discover.ts","lineNumber":146,"sourceCode":"\t\t});\n\t}\n\tif (parsed === null || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n\t\tthrow new AIError.ConfigurationError(\"OMP_AUTH_BROKER_ACCOUNT_POOL_FILE must contain a JSON object\");\n\t}\n\n\tconst accountPool = new Map<string, ReadonlySet<string>>();\n\tfor (const [provider, value] of Object.entries(parsed)) {\n\t\tconst normalizedProvider = provider.trim();\n\t\tif (normalizedProvider.length === 0) {\n\t\t\tthrow new AIError.ConfigurationError(\"OMP_AUTH_BROKER_ACCOUNT_POOL_FILE contains an empty provider id\");\n\t\t}\n\t\tif (provider !== normalizedProvider) {\n\t\t\tthrow new AIError.ConfigurationError(\n\t\t\t\t\"OMP_AUTH_BROKER_ACCOUNT_POOL_FILE contains a provider id with surrounding whitespace\",\n\t\t\t);\n\t\t}\n\t\tif (!Array.isArray(value)) {\n\t\t\tthrow new AIError.ConfigurationError(\n\t\t\t\t`OMP_AUTH_BROKER_ACCOUNT_POOL_FILE entry for ${provider} must be an array of identity keys`,\n\t\t\t);\n\t\t}\n\t\tconst identities = new Set<string>();\n\t\tfor (const identity of value) {\n\t\t\tif (typeof identity !== \"string\" || identity.length === 0) {\n\t\t\t\tthrow new AIError.ConfigurationError(\n\t\t\t\t\t`OMP_AUTH_BROKER_ACCOUNT_POOL_FILE entry for ${provider} contains an invalid identity key`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (identity !== identity.trim()) {\n\t\t\t\tthrow new AIError.ConfigurationError(\n\t\t\t\t\t`OMP_AUTH_BROKER_ACCOUNT_POOL_FILE entry for ${provider} contains an identity key with surrounding whitespace`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tidentities.add(identity);\n\t\t}\n\t\taccountPool.set(provider, identities);","sourceCodeStart":128,"sourceCodeEnd":164,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/ai/src/auth-broker/discover.ts#L128-L164","documentation":"Each provider's value in the pool file must be an array of identity-key strings. If the value for a provider is an object, string, number, or null instead of an array, the loader throws this ConfigurationError naming the offending provider. The array shape is required because each provider maps to a set of allowed identity keys.","triggerScenarios":"OMP_AUTH_BROKER_ACCOUNT_POOL_FILE maps a provider to a non-array, e.g. { \"openai\": \"acc1\" } or { \"openai\": { \"default\": \"acc1\" } } instead of { \"openai\": [\"acc1\"] }.","commonSituations":"Older pool-file format using a single identity string per provider, migrated files that kept the scalar form, or hand-written configs where the brackets around the identity list were omitted.","solutions":["Change the provider's value to an array: wrap the identity key(s) in [ ].","If migrating from a scalar-per-provider format, map each value to a single-element array during conversion.","Validate per-entry: `jq 'to_entries | map(select(.value | type != \"array\"))' pool.json` should return [].","Update any script that writes the pool file to serialize arrays for every provider."],"exampleFix":"// before (account-pool.json)\n{\n  \"openai\": \"acc1\"\n}\n\n// after\n{\n  \"openai\": [\"acc1\"]\n}","handlingStrategy":"validation","validationCode":"function validateEntryArrays(pool: Record<string, unknown>): void {\n  for (const [provider, value] of Object.entries(pool)) {\n    if (!Array.isArray(value)) {\n      throw new Error(`entry for ${provider} must be an array of identity keys`);\n    }\n  }\n}","typeGuard":"function isIdentityKeyArray(v: unknown): v is string[] {\n  return Array.isArray(v) && v.every((x): x is string => typeof x === \"string\");\n}","tryCatchPattern":"try {\n  const pool = await loadAuthBrokerAccountPool();\n} catch (err) {\n  if (err instanceof AIError.ConfigurationError && err.message.includes(\"must be an array of identity keys\")) {\n    logger.error(\"pool file provider entry is not an array; wrap identity keys in [ ]\");\n  } else throw err;\n}","preventionTips":["Always serialize provider values as arrays, even for a single identity key: [\"acc1\"].","When migrating from older scalar formats, convert values with a mapping step.","Validate in CI: `jq 'to_entries | map(select(.value | type != \"array\")) | length' pool.json` must be 0.","Keep the writer script and the reader's schema in sync — version the pool file format if it changes."],"tags":["configuration","json","schema-validation","auth-broker"],"backgroundTag":"schema-validation-failed","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}