mastra-ai/mastra · error · HTTPException

No writable mount available for skill installation

Error message

No writable mount available for skill installation

What it means

Thrown by buildSkillInstallPath when installing a skill without specifying a mount in a CompositeFilesystem where every registered mount is read-only. The server cannot find any mount to write into and responds with HTTP 403. It exists to fail fast instead of attempting a doomed write.

Source

Thrown at packages/server/src/server/handlers/workspace.ts:227

      if (!mountFs) {
        throw new HTTPException(400, {
          message: `Mount "${requestedMount}" not found. Available mounts: ${filesystem.mountPaths.join(', ')}`,
        });
      }
      if (mountFs.readOnly) {
        throw new HTTPException(403, { message: `Mount "${requestedMount}" is read-only` });
      }
      return `${stripTrailingSlash(requestedMount)}/${SKILLS_SH_DIR}/${safeSkillId}`;
    }

    // Default: use first writable mount
    for (const [mountPath, mountFs] of filesystem.mounts) {
      if (!mountFs.readOnly) {
        return `${stripTrailingSlash(mountPath)}/${SKILLS_SH_DIR}/${safeSkillId}`;
      }
    }

    throw new HTTPException(403, { message: 'No writable mount available for skill installation' });
  }

  // Non-composite: standard path
  return `${SKILLS_SH_DIR}/${safeSkillId}`;
}

// =============================================================================
// List All Workspaces Route
// =============================================================================

export const LIST_WORKSPACES_ROUTE = createRoute({
  method: 'GET',
  path: '/workspaces',
  responseType: 'json',
  responseSchema: listWorkspacesResponseSchema,
  summary: 'List all workspaces',
  description: 'Returns all workspaces from both Mastra instance and agents',
  tags: ['Workspace'],

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Configure at least one writable mount in the workspace's CompositeFilesystem (readOnly: false) and retry.
  2. Or enable skill installation only in environments where a writable mount exists; gate the install step by environment.
  3. Verify with GET the workspace's filesystem/mounts that at least one mount lacks the readOnly flag before installing.

Example fix

// before: all mounts read-only
new CompositeFilesystem({ mounts: { '/data': fs({ readOnly: true }) } })
// after: add a writable mount for skills
new CompositeFilesystem({ mounts: { '/data': fs({ readOnly: true }), '/workspace': fs({ readOnly: false }) } })
Defensive patterns

Strategy: validation

Validate before calling

const mountInfo = await getWorkspaceMountInfo(workspaceId);
if (!mountInfo.some(m => !m.readOnly)) {
  throw new Error('Workspace has no writable mount; skill installation is impossible until config changes');
}

Type guard

function hasWritableMount(mounts: { readOnly: boolean }[]): boolean {
  return mounts.some(m => !m.readOnly);
}

Try / catch

try {
  await installSkill({ workspaceId, skillId });
} catch (e) {
  if (isHttpException(e, 403) && e.message.includes('No writable mount')) {
    logger.warn('Skipping skill install: workspace is fully read-only');
    return { skipped: true };
  }
  throw e;
}

Prevention

When it happens

Trigger: POSTing to the skill install endpoint (installPath) with no mount parameter against a workspace whose CompositeFilesystem has all mounts configured readOnly: true, or whose only writable mount was switched to read-only after a config update.

Common situations: Production/staging environments locked down to read-only filesystems where skills.sh installs are still attempted; forgotten migration after mounting datasets or templates as immutable.

Related errors


AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30). Data as JSON: /api/errors/e66c3e5ef0a1fa94. Report an issue: GitHub.