Docs › Slima MCP › Permission denied on write

Permission denied on write

Last updated September 9, 2026 · 8 min read

In one line: how to tell the reasons a write gets refused apart, and what each one's next step is.

Read the code before you retry

A refused write has several unrelated causes, and their fixes have nothing in common. The error code is how you tell them apart:

Code Status What it means Next step
AI_READONLY_FILE_TYPE 403 This type takes no whole-file write Structured file: use the update_* tool the message names. .character / .json and friends: there is no alternative
SUBSCRIPTION_REQUIRED 403 The capability belongs to the subscription plans Reading is not restricted — read it and describe the change you recommend
INVALID_PATH 400 An older Script Studio book, written outside the planning tree Write under .script_studio/planning/ instead
FOLDER_NOT_EMPTY 422 The folder you asked to delete has things in it If you mean it, resend with recursive: true

In none of those four does resending the same arguments turn into a success.

1 · Structured files: the message names the tool

Aim write_file, edit_file or append_to_file at a .map, .beats, .timeline, .script or .geomap and you get this back:

.map files are structured documents — a generic write would corrupt them.
Use POST /api/v1/books/:book_token/mcp/files/structured (the MCP client
exposes it as update_relationship_map): it takes one field-level operation at
a time, so the parts of the document you were never shown cannot be dropped.
If update_relationship_map is not in your tool list, your Slima MCP client is
older than this server — ask the author to update the Slima MCP package.
A missing tool always means an out-of-date client; nothing about this account
ever hides a tool from you.

Two things are in there: which tool to use, and what to do when that tool is not in your list. The second matters, because 0.2.0 does not have those tools and the server does not accept whole-file writes either — an old client has both routes shut. Upgrading is covered in How slima-mcp versions work.

.character, .location, .json and .yaml return the same code without the alternative route: read the file, then say in words what you would change.

2 · The subscription gate: reading is never restricted

When the plan has not unlocked structured writing, the code is SUBSCRIPTION_REQUIRED and the message reads:

Writing .map files is part of Slima's subscription plans. Reading them is not
restricted — read the file and describe the change you recommend, and the
author can make it in the app or subscribe to let you make it directly.
(Credits bought as a one-off pack cover AI usage inside the Slima app;
structured file writing goes with a plan.)

Three things follow from it:

  • Reading is untouched. An AI on a free account can read every .map and .timeline in the book. It just cannot change them.
  • The test is the plan, not whether money was ever spent. A one-off credit pack covers AI usage inside the Slima app; it does not unlock structured writing.
  • Deleting is gated the same way as writing. On a free plan a .map cannot be created, cannot be edited, and cannot be deleted either.

The useful response here is not a retry. It is to read the file and say precisely what you would change, so the author can do it in the app.

3 · Older Script Studio books: INVALID_PATH

If the book is an older Script Studio book, a completely separate rule set applies, and it works on paths: the only writable area is the .script_studio/planning/ tree, while series.json, *.character, *.location, *.scene, *.storyline, *.note and .script_studio/planning/.initialized are all read-only over MCP.

.script_studio/planning/scene-3-1-revision.md   ← writable
Episodes/03/scene-1.scene                        ← 400 INVALID_PATH

The way through is to write the proposal into that planning tree and let the author apply it in the app. To know the rules before you try, read the slima://books/{book_token}/schema resource, or just call get_book — on such a book it prints its own write restrictions.

4 · The one that is easiest to miss: it succeeded, and the file is empty

create_file is not refused on the five structured extensions. It succeeds — and what the server wrote is an empty skeleton, with the content you sent dropped. The reply says so plainly.

Because it is not a failure, it reads as "created". The correct flow is two steps: create_file for an empty one, then update_* batches to fill it.

Two causes that are not about file type

  • The book is in the trash. A trashed book is not writable. Restore it first.
  • The book was shared with you. Without write-level access on that book, you can only read.

Do not route around a refusal

Slima's MCP errors are written to be fixable from the message: an unknown id comes back with the real ids, an unknown place tier with the real tiers, a misplaced field with the name of the operation that owns it. The cost of a workaround lands on the author; the cost of reading the message lands on you, and it is much the cheaper of the two.

Related

Try it in Slima

Open the app and do this with your own book. Free to start, no credit card.

Open Slima
Was this helpful?