danny-avila/LibreChat · error · Error
Storage backend "${source}" does not support file writes
Error message
Storage backend "${source}" does not support file writes What it means
Thrown by resolveSkillStorage in the skills route when the file strategy resolved for the skill_file context has no saveBuffer function. The selected storage backend (e.g. local, s3) must implement buffer writes for skill file creation/import to work; a backend that only supports reads is rejected.
Source
Thrown at api/server/routes/skills.js:150
? withDeploymentSkillIds(await findPubliclyAccessibleResources(params))
: findPubliclyAccessibleResources(params),
hasPublicPermission: async (params) =>
params.resourceType === 'skill' && params.requiredPermissions === PermissionBits.VIEW
? withDeploymentSkillIds([]).some((id) => id.toString() === params.resourceId.toString()) ||
hasPublicPermission(params)
: hasPublicPermission(params),
grantPermission,
isValidObjectIdString,
});
// ---------------------------------------------------------------------------
// File storage helper: resolve the active strategy's saveBuffer
// ---------------------------------------------------------------------------
function resolveSkillStorage(req, { isImage = false } = {}) {
const source = getFileStrategy(req.config, { context: FileContext.skill_file, isImage });
const strategy = getStrategyFunctions(source);
if (!strategy.saveBuffer) {
throw new Error(`Storage backend "${source}" does not support file writes`);
}
return { saveBuffer: strategy.saveBuffer, source };
}
// ---------------------------------------------------------------------------
// Import handler (zip/md/skill → create skill + files)
// ---------------------------------------------------------------------------
const importHandler = createImportHandler({
limits: (req) => ({
maxZipBytes: getSkillImportSizeLimit(req),
}),
createSkill,
getSkillById,
deleteSkill,
upsertSkillFile,
saveBuffer: (req, { userId, buffer, fileName, basePath, isImage, tenantId }) => {
const requestTenantId = tenantId ?? resolveRequestTenantId(req);
const storage = resolveSkillStorage(req, { isImage });View on GitHub (pinned to 5ff282f900)
Solutions
- Point the skill_file context at a strategy that implements saveBuffer (local or s3).
- If using a custom strategy, implement and register a saveBuffer method on it.
- Verify FILE_STRATEGY / getFileStrategy config returns the expected backend for the skill context.
- Disable skill file import/upload until a writable backend is configured.
Defensive patterns
Strategy: validation
Validate before calling
const strategy = getStrategyFunctions(source);
if (typeof strategy.saveBuffer !== 'function') {
throw new Error(`Refusing skill import: backend '${source}' cannot write files`);
} Type guard
function strategyCanWrite(strategy) {
return strategy != null && typeof strategy.saveBuffer === 'function';
} Try / catch
try { await importHandler(req, res); }
catch (e) { if (/does not support file writes/.test(e.message)) return res.status(400).json({ error: 'Configured storage cannot receive skill files' }); throw e; } Prevention
- Smoke-test saveBuffer at startup for the configured skill_file strategy.
- Keep a writable strategy (local/s3) for any environment that allows skill uploads.
- Document which storage backends are write-capable.
When it happens
Trigger: The configured FILE_STRATEGY (or the value returned by getFileStrategy for the skill_file context) points at a read-only or partially-implemented strategy whose getStrategyFunctions result lacks saveBuffer.
Common situations: A custom storage plugin registered without a saveBuffer implementation; deployment wired to a read-only CDN source; a deployment-mode skill file source selected where writes are not supported.
Related errors
- Storage backend "${source}" does not support file writes
- RAG_API_URL not defined
- [${req.baseUrl}] Invalid version: ${version}
- Agent not found
- Subagent run configuration exceeds the maximum of ${MAX_SUBA
AI-assisted analysis of danny-avila/LibreChat@5ff282f900 (2026-08-12).
Data as JSON: /api/errors/ec02fdf35a935f02.
Report an issue: GitHub.