{"record":{"id":"8ad13346f840545a","repo":"SillyTavern/SillyTavern","slug":"apiname-did-not-return-an-array","errorCode":null,"errorMessage":"${apiName} did not return an array","messagePattern":"(.+?) did not return an array","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/vectors/google-vectors.js","lineNumber":36,"sourceCode":"        })),\n    };\n\n    const response = await fetch(url, {\n        body: JSON.stringify(body),\n        method: 'POST',\n        headers: headers,\n    });\n\n    if (!response.ok) {\n        const text = await response.text();\n        console.warn(`${apiName} batch request failed`, response.statusText, text);\n        throw new Error(`${apiName} batch request failed`);\n    }\n\n    /** @type {any} */\n    const data = await response.json();\n    if (!Array.isArray(data?.embeddings)) {\n        throw new Error(`${apiName} did not return an array`);\n    }\n\n    const embeddings = data.embeddings.map(embedding => embedding.values);\n    return embeddings;\n}\n\n/**\n * Gets the vector for the given text from Google Vertex AI\n * @param {string[]} texts - The array of texts to get the vector for\n * @param {string} model - The model to use for embedding\n * @param {import('express').Request} request - The request object to get API key and URL\n * @returns {Promise<number[][]>} - The array of vectors for the texts\n */\nexport async function getVertexBatchVector(texts, model, request) {\n    const { url, headers, apiName } = await getGoogleApiConfig(request, model, 'predict');\n\n    const body = {\n        instances: texts.map(text => ({ content: text })),","sourceCodeStart":18,"sourceCodeEnd":54,"githubUrl":"https://github.com/SillyTavern/SillyTavern/blob/8172dcd0ee672d3cd9a5e5f7af134f91a45cd2b8/src/vectors/google-vectors.js#L18-L54","documentation":"After a successful Google batch embedding response, the code asserts Array.isArray(data?.embeddings); if absent it throws `${apiName} did not return an array`. This guards the expected response shape where data.embeddings is an array of objects each with a `.values` field.","triggerScenarios":"Google returns 2xx but data.embeddings is missing or not an array: response schema changed, the request produced an empty result, or an error envelope was returned with 2xx by a proxy.","commonSituations":"Google API version change altering the response structure, empty input texts array producing an empty/absent embeddings field, or a gateway rewriting the body.","solutions":["Inspect the actual response body to confirm the returned shape.","Ensure the texts array passed in is non-empty and valid.","Update the parser if Google changed the field name for this API version.","Rule out an intermediary proxy returning a non-standard body."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Ensure the batch is non-empty and texts are strings\nif (!Array.isArray(texts) || texts.length === 0 || texts.some(t => typeof t !== 'string')) {\n    throw new Error('texts must be a non-empty array of strings');\n}","typeGuard":"function isGoogleBatchResponse(data) {\n    return !!data && Array.isArray(data?.embeddings);\n}","tryCatchPattern":"try {\n    return await getGoogleBatchVector(texts, model, request);\n} catch (e) {\n    if (e.message.endsWith('did not return an array')) {\n        // log raw body; degrade gracefully\n    } else throw e;\n}","preventionTips":["Log the raw response body on shape mismatch to detect schema drift.","Pin to a stable Google API version.","Ensure no intermediary proxy rewrites the response.","Validate the texts batch is non-empty before sending."],"tags":["vectors","google","validation","embeddings","external-api"],"backgroundTag":null,"analyzedSha":"8172dcd0ee672d3cd9a5e5f7af134f91a45cd2b8","analyzedAt":"2026-08-13T07:48:40.832Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}