nocobase/nocobase · error · Error
Kimi extract failed for "${sourceFile.filename}": ${message}
Error message
Kimi extract failed for "${sourceFile.filename}": ${message} What it means
After uploading a file to Kimi, parseByApi calls client.files.content(uploadedFileId) to retrieve the extracted text. If that call rejects, formatApiError normalizes the underlying error message (error.error.message, response.data..., error.message) into 'Kimi file extraction failed for "<filename>": <message>'. This wraps any network/HTTP/auth failure of the extraction step.
Source
Thrown at packages/plugins/@nocobase/plugin-ai/src/server/llm-providers/kimi/document-loader.ts:79
uploaded = await this.client.files.create({
file: createReadStream(tempFilePath),
// @ts-ignore
purpose: 'file-extract',
});
} catch (error) {
throw new Error(this.formatApiError(error, sourceFile, 'upload'));
}
uploadedFileId = uploaded?.id;
if (!uploadedFileId) {
throw new Error('Kimi files.create response missing id');
}
let parsedResponse: any;
try {
parsedResponse = await this.client.files.content(uploadedFileId);
} catch (error) {
throw new Error(this.formatApiError(error, sourceFile, 'extract'));
}
if (typeof parsedResponse?.text === 'function') {
return await parsedResponse.text();
}
return typeof parsedResponse === 'string' ? parsedResponse : String(parsedResponse ?? '');
} finally {
await fs.rm(tempFilePath, { force: true });
if (uploadedFileId) {
await this.deleteRemoteFile(uploadedFileId);
}
}
}
private async deleteRemoteFile(fileId: string) {
try {
await this.client.files.delete(fileId);
} catch (error) {
// Ignore cleanup errors to avoid blocking main parsing flow.View on GitHub (pinned to fa42722fef)
Solutions
- Read the wrapped <message> for the real cause (401 → fix API key; 404 → check baseURL consistency; 429 → back off and retry).
- Confirm apiKey is valid and active for api.moonshot.cn, and that baseURL (if overridden) points to the same service the file was uploaded to.
- Check the uploaded file's format/size is supported by Kimi file-extract.
- Retry with backoff for 429/5xx; check network/proxy connectivity to api.moonshot.cn.
Example fix
// before
parsedResponse = await this.client.files.content(uploadedFileId);
// after (retry transient failures)
for (let i = 0; i < 3; i++) {
try { parsedResponse = await this.client.files.content(uploadedFileId); break; }
catch (e) { if (i === 2) throw e; await new Promise((r) => setTimeout(r, 1000 * 2 ** i)); }
} Defensive patterns
Strategy: try-catch
Validate before calling
// preflight: key + connectivity check before parsing files
const res = await fetch(`${baseURL}/models`, { headers: { Authorization: `Bearer ${apiKey}` } });
if (!res.ok) throw new Error(`Kimi unreachable/unauthorized: ${res.status}`); Try / catch
try {
const docs = await loader.load(file);
} catch (err) {
if (/Kimi file extraction failed/.test(err.message)) {
const cause = err.message.split(': ').slice(1).join(': ');
logger.warn(`Kimi extract failed for ${file.filename}: ${cause}`);
// 429/5xx -> retry with backoff; 401 -> surface credential error to admin
} else throw err;
} Prevention
- Validate the API key at provider save time with a cheap /models call.
- Keep upload and content calls on the same baseURL.
- Add retry-with-backoff for 429/5xx in bulk parsing jobs.
- Monitor Moonshot status/quotas during large ingestion runs.
When it happens
Trigger: client.files.content(uploadedFileId) throws: 401 invalid API key, 404 file not found (file expired or wrong baseURL routing to a different backend than the upload), 429 rate limit, 5xx from Moonshot, or network timeout/DNS failure while fetching content.
Common situations: Expired or revoked Kimi API key; baseURL mismatch so the content lookup hits a different service; uploading a file type Moonshot rejects for extraction; hitting Moonshot rate limits during bulk document parsing.
Related errors
- formatDockerDownloadFailure(runtime.envName, message)
- formatLocalDownloadFailure(runtime.envName, runtime.source,
- Docker could not create network "${name}" because its addres
- Failed to fetch commercial plugins with status ${response.st
- download failed with status ${response.status}
AI-assisted analysis of nocobase/nocobase@fa42722fef (2026-09-01).
Data as JSON: /api/errors/7975806bf6eb5425.
Report an issue: GitHub.