Troubleshooting DocsFab
The following issues might arise when you work with
DocsFab. Most DocsFab failures print a code: line and a
Next action: line. Follow the printed next action first. If the code is
listed in Error Messages, use that table for more detail.
A Command Reports That Git Is Unavailable
When you run docsfab init, docsfab run, or docsfab publish, you might
see a message that Git is unavailable. These commands read an exact Git
revision, so they check for Git before they start.
To resolve this issue, install Git, make sure git is on PATH, and open a
new shell. Then confirm that git --version succeeds, and rerun the
command.
A Draft Merge Request Is Not Created After a Successful Run
When a write workflow succeeds but delivery stops, the documentation change is
saved with the run. The output can show stale-revision, publication-failed,
or another delivery code, and NEXT prints a recovery command.
To resolve this issue, do not run the workflow again. Run the printed recovery command, which includes the exact paths that the stopped attempt used. In most cases, the command is one of the following:
To review the publication plan before DocsFab opens the merge request, run the two-step form:
If stale-revision appears before the write, no run is saved. Run
docsfab doctor --repo <path> to check the checkout and the GitLab target
branch, update the checkout, and start the run again. If it appears after the
write, the write is saved. Merge the run base into the target branch, and then
run docsfab ship <run-id> --repo <path>.
If delivery stops with run-revision-unpushed, the run started from a commit
that GitLab does not have, such as a local commit that was never pushed.
DocsFab does not push it for you. Push that commit to the target branch, for
example with git push origin <run-base>:<target-branch>, and then run
docsfab ship <run-id> --repo <path>. To publish without that commit, start a
new run from the target branch instead.
A failed delivery can retain local worktrees or branches. When that state is
verified, the output and PUBLICATION section list the preserved resources
and a cleanup preview command. You can inspect the current retained state
later with docsfab runs show <run-id>; pass
--state-dir if you selected a different run store. The JSON result has an
optional outer retainedDelivery field, independent of the saved merge-request
lookup in publication and the workflow result. A retry reuses a verified
retained attempt instead of adding another worktree. Changed attempts stay
available for inspection.
When you no longer need the run, copy the printed cleanupPreviewCommand
exactly. It includes the applicable state, delivery, and receipt directories,
including verified custom locations. Review the preview’s removal and kept
resource lists, then run its returned confirmation command if you want to
delete that state. DocsFab does not perform this cleanup automatically or
treat the displayed command as confirmation. User branches, worktrees with
uncommitted changes, and resources outside the verified deletion scope stay
protected. Remote branches and merge requests remain on GitLab.
If retainedDelivery.status is inspection-required, some details could not
be verified or displayed safely. Inspect the original publication directories
and settings before requesting a fresh deletion preview. A
cleanupPreviewCommand of null means no safe command is available; do not
guess roots or run a command with redacted paths. For more information, refer
to Delete a Saved Run.
For other delivery codes, refer to Error Messages.
The Saved Run Record Was Not Found
docsfab ship and docsfab publish report saved-run-not-found when the
selected saved record is absent, including after you delete it. This is an
operator-input refusal, not a diagnosis that the record is malformed. DocsFab
does not reconstruct the deleted run or start publication from its ID.
Run docsfab runs list in the same configuration context and select an
existing run. If you passed --state-dir to publish, pass the same directory
to runs list; ship uses the configured run store. Correct an unintended run
ID or state-directory selection before retrying. Existing unreadable, unsafe,
or malformed records retain their own refusal.
A Request That Says Not to Publish Is Refused
When a docsfab do sentence or a --instruction value says not to publish,
push, or open a merge request, you might see the following message:
publication-prohibition-conflict. Create, update, and restructure workflows
open a draft merge request by default, so DocsFab stops instead of choosing
between your instruction and the default delivery.
To resolve this issue, pass --patch-only to keep the result as a local
patch, or remove the instruction not to publish.
A Run Stops Because a Configured Credential Was Found
When a source file, a merge request, or your request text contains one of the
credentials that DocsFab itself uses, such as its model key, the run or the
read stops with credential-material. A live agent session reports
Blocked by DocsFab runtime credential screening. Text that only looks like a
credential, such as a sample key in an example, is reported as a
credential-like-content finding, and the run continues.
To resolve this issue, remove the credential from the source, commit the change, and rotate the credential with your provider, because it was exposed. Then start a new run. Do not paste credentials into requests, chat, or issue reports.
A Run Stops With needs-input
When DocsFab needs more information, the run stops with needs-input and
exit code 2, and NEXT tells you what to provide. This can happen at the
following two points:
- Before a workflow starts:
docsfab doprintsOutcome route: needs-inputbecause the sentence matched no workflow or more than one. Restate the request in one sentence that names the task, the target page, and the outcome, or run a workflow directly withdocsfab run. - After a workflow starts: the run lists the missing items under
PRODUCT, such as a source file for a fact that DocsFab cannot verify. Add the missing file to the repository, commit it, and run the printeddocsfab do --continue <run-id>command, or start a new run that names the file with--source.
If the run stopped during planning, docsfab do --continue reports
continue-planner-input-unsupported, because a planning stop cannot continue.
Run docsfab do --continue again from the original repository, and pass
--repo ., the run ID, and a committed source file with --attach. DocsFab
prints a complete docsfab run command that keeps the original instruction,
adds the file as --source, and pins the current committed revision. You can
pass --revision <ref> to nominate a different committed revision. DocsFab
checks every selected source at that revision before offering the command.
Copy the command to start a new run. The stopped run stays unchanged.
A planning needs-input stop exits with code 2. If no file changed before
the stop, DocsFab does not save an empty patch.
When a create, update, or restructure run ends with writer-made-no-change,
the writer could not satisfy an instruction and asks one question. Add the
answer to your instruction and start a new run.
For more information, refer to Answer and Resume.
An Unexpected Failure Does Not Explain the Cause
When a run or a live agent action fails, you might see a message such as
No safe failure detail is available or a code that the run describes as a
DocsFab defect, such as context-compile-failed. These failures do not have a
fix that you can apply.
To resolve this issue, collect the details and report the problem to the DocsFab maintainers:
- Find the run ID in the output, and run
docsfab why <run-id> --json. - If the failure happened in a live agent session, find the session
transcript under
~/.config/docsfab/.docsfab/live-agent/sessions/. Run records are under~/.config/docsfab/.docsfab/runs/. If you setDOCSFAB_CONFIG_ROOT, look under that directory instead. - Remove any credentials or private content, and include the output in your report.
Starting the same run again without changes usually fails the same way.
An Update Run Fails Because a Cited Source Cannot Be Read
When you run update-documentation, the run might fail at the
derive-source-obligations step with source-locator-unobservable. Older
installations report not-tracked and Tracked repository file read failed
instead. The model cited a file that DocsFab cannot read as evidence, such as
a missing or untracked file, a symbolic link, or a file that is larger than the
source file limit. DocsFab asks the model to correct the citation within its
retry limit before the run fails.
To resolve this issue, run docsfab runs show <run-id> to see where the
rejected citation came from and, when DocsFab can name it, which file it cited.
Check that the file is committed, is a regular file, and is within the size
limit, and then start a new run. A saved patch does not mean that the update
succeeded. The update succeeded only when derive-source-obligations and the
later steps complete.
Installation Fails
Use these steps to resolve common source installation errors:
-
For
EBADENGINE, checknode --versionand use Node.js 24.21.0 or later. -
For dependency or build failures, confirm the checkout is complete, then rerun
npm --prefix packages/runtime ciandnpm --prefix packages/runtime run buildfrom the checkout root. -
For
EACCESor a global-prefix permission error, configure a user-owned global prefix and add itsbindirectory toPATH:Add the
PATHline to your shell startup file before opening a new shell. Do not makesudo npmthe default. -
If you cannot clone the source repository, ask its owner to grant repository access before following the installation steps.
Registry Authentication or Download Fails
For an alternative registry installation, E401, E403, or E404 can mean
that npm cannot authenticate. Confirm that your approved host credential
facility supplies NPM_TOKEN, that the token can read the package registry,
and that the user-level npm configuration includes the full project registry
path. A private package can return HTTP 404 when npm is unauthenticated.
Browser and glab authentication do not replace npm authentication.
Refer to GitLab’s npm registry authentication documentation.
Also confirm that the exact package version and tarball URL exist in GitLab. For a network or download error, restore access to the internal GitLab host, then retry the same exact URL.
DocsFab Reports That Node.js Is Unsupported
When you run any docsfab command, you might see the following message:
DocsFab requires Node.js >=24.21.0; found <version>. This message appears
when the shell resolves an older Node.js, including a shell that was opened
before you installed or selected a newer version.
To resolve this issue, install Node.js 24.21.0 or later, or select it with
your version manager, such as nvm use 24. Then open a new shell and
confirm that node --version and docsfab --version both succeed. If you use
a version manager, install DocsFab again under the new Node.js version.
DocsFab Reports That the Platform Is Unsupported
When you run DocsFab on Windows, you might see a message that the platform is unsupported. DocsFab runs on Linux and macOS only.
To resolve this issue on Windows, install DocsFab inside a Linux distribution
on WSL 2, such as Ubuntu 24.04. Keep the DocsFab installation, the DocsFab
configuration directory, and the repositories that you document in the Linux
file system, such as your home directory. Windows drives that WSL mounts
under /mnt/ do not keep the owner-only file permissions that DocsFab
requires for its configuration.
For more information, refer to Install DocsFab.
Doctor Reports Blocked Readiness
When you run docsfab doctor --repo <path>, you might see
DocsFab readiness: blocked and one or more diagnostic codes, such as
project-config-missing, provider-credentials-missing, or
private-state-missing. Each diagnostic prints its own Next action: line.
To resolve this issue, follow each printed next action. For
project-config-missing or private-state-missing, preview
docsfab init first, and then apply the plan with the digest it prints. For
provider-credentials-missing, refer to
No Model Profile or Model Key Is Configured.
A blocked gitlab check affects only draft merge request delivery. Runs with
--patch-only do not need GitLab.
For more information, refer to Runtime Readiness and Doctor Checks in DocsFab.
GitLab Authentication or Connection Fails During Delivery
When DocsFab opens a draft merge request, you might see one of the following codes:
glab-auth-loginorgitlab-unauthenticated:glabis not logged in to the GitLab host for the selected Git remote. Runglab auth login --hostname <host>, using the host fromgit remote get-url origin.gitlab-unreachable: the GitLab API for that host did not respond. Check your network or VPN connection, and confirm thatglab api --hostname <host> usersucceeds. Do not log in again unlessglab auth status --hostname <host>reports that you are not logged in.glab-unavailable: theglabcommand is not installed or is not onPATH. Install the GitLab CLI, or pass--patch-onlyto skip merge request delivery.
DocsFab does not store GitLab credentials. After the fix, recover the saved run as described in A Draft Merge Request Is Not Created After a Successful Run.
A Draft Merge Request Is Stopped by a Git Setting
When you run a write workflow that opens a draft merge request, or when you
publish a saved run, you might see git-configuration-refused. The message
names the setting and the file that sets it, for example
The setting core.sshcommand comes from file:.git/config. DocsFab checks the
Git configuration before it starts the model, so a refusal at that point costs
no model call and creates no run. docsfab doctor --live runs the same check
and reports the refusal as a blocker for the draft merge request. DocsFab checks
again at publication, before it commits, before it pushes, and before it opens
the merge request. A publication that fails with this code saves the write. The
state in the publication result shows how far publication got. A state of
planned, prepared, or validated means that DocsFab had not committed. A
state of committed means that it had committed and pushed nothing. A state
of pushed means that it had pushed the branch and opened no merge request.
The checkout’s Git configuration, or your global or system Git configuration, holds a setting that can run a command, change how DocsFab pushes, or turn signing on. The check before the model run and the check at publication apply one policy. DocsFab refuses these settings in any Git configuration file:
core.hooksPath,core.fsmonitor, andcore.gitProxyremote.<name>.receivepack,remote.<name>.uploadpack,remote.<name>.proxy,remote.<name>.mirror, andremote.<name>.pushOptionhttp.<url>.extraHeader,http.<url>.proxy, andpush.pushOption- a credential helper for the GitLab host that runs a shell command (a value
that starts with
!)
DocsFab refuses these settings unless they come from a Git configuration file that it trusts:
core.sshCommandandcore.askPasscommit.gpgSignandtag.gpgSignset to anything other than a false value,gpg.*, anduser.signingKeyurl.<base>.insteadOfandurl.<base>.pushInsteadOfinclude.pathandincludeIf.<condition>.path- any credential helper for the GitLab host
DocsFab accepts commit.gpgSign and tag.gpgSign from any file when the value
is false, no, off, or 0. The match is not case sensitive. DocsFab turns
signing off on its own Git commands, so a repository that turns it off asks for
nothing.
DocsFab trusts only these Git configuration files:
- your global files,
~/.gitconfigand~/.config/git/config - the system files
/etc/gitconfig,/usr/local/etc/gitconfig, and/usr/share/git-core/gitconfig - the same
usr/share/git-core/gitconfigfile under/Library/Developer/CommandLineToolsand/Applications/Xcode.app/Contents/Developer - the
etc/gitconfigfile of a Git for Windows installation underProgram FilesorProgram Files (x86)
A setting from any other file is not trusted. That includes the checkout’s own
configuration, a file that another configuration file includes, and a system
file at another path. For example, Homebrew Git on Apple silicon sets a
credential helper in /opt/homebrew/etc/gitconfig, and DocsFab refuses it.
For core.sshCommand and core.askPass, a global file counts only when the
HOME environment variable is an absolute path that is not inside the
checkout. Git reads a relative HOME, such as ~ or ., as a path in the
directory where it runs, and a file under a HOME inside the checkout can come
from the repository. DocsFab refuses both settings from such a file, and the
message says that HOME is the reason. The system files always count, and
every other setting that DocsFab accepts from a trusted file is accepted as
before.
To find the setting, list the configuration that Git applies in the checkout,
with the file that each setting comes from. If the setting is core.sshCommand
or core.askPass in a global file, check that HOME is an absolute path
outside the checkout:
To resolve this issue, remove the refused setting from the file that sets it. A
core.sshCommand or core.askPass in the checkout’s own configuration can move
to your global Git configuration, where DocsFab accepts it when HOME is an
absolute path outside the checkout. To use a different SSH key for one host, you
can set IdentityFile for that host in your SSH configuration instead. A
signing key, URL rewrite, include, or credential helper can also move to your
global Git configuration. Then run the same command again. If DocsFab had
already written the change, retry publication of the saved run instead. The
workflow does not run again:
A retry that still finds a refused setting fails with
git-configuration-refused again and keeps the publication retryable, even
after DocsFab committed. When the setting is gone, the retry publishes the
preserved write. A publication that an earlier failure had already recovered to
patch-only cannot publish again. It reports the refused setting with the next
action review-preserved-patch, so review the preserved patch instead.
After you remove the setting, the run starts the model, or the retry opens the draft merge request, or either fails with a different typed code.
Repository Access
When DocsFab reports repository-ownership-mismatch, Git refused to read the
selected repository because its ownership does not match the current process.
When DocsFab reports repository-access-denied, Git could not read the
selected repository with the current process permissions. These frozen
messages appear in the standard operator error envelope. Both errors have the
operator-input classification at the host failure layer. The repository
preflight runs before workspace materialization. An earlier intent-admission
step might already have made a model call.
These codes identify failures recognized during repository preflight. A later
tree or blob read can still report a materialization error.
Git ownership protection and filesystem permissions are separate checks. A checkout can be readable but rejected by Git because another user owns it. A checkout can also have the expected owner while denying the runtime user read access to files or search access to a directory.
To resolve either error, run DocsFab as the checkout owner, or prepare a dedicated CI or container checkout for the DocsFab user. If ownership already matches, grant that user read access to repository files and Git metadata, and search access to parent and repository directories. A read-only source mount can work when those permissions are present. Keep writable runtime state and exported run results in separate directories. In container or CI setups, verify the user and mounts before retrying.
Do not recursively change ownership across a customer repository as a general
fix, and do not disable Git’s ownership protection with safe.directory=*.
Repair only the checkout or private job copy that you own. A permission or
ownership failure is distinct from git-configuration-refused and
git-checkout-unverified; follow the printed next action for those Git
configuration errors.
For setup guidance, refer to Runner Quickstart.
DocsFab Cannot Verify the Git Setup of a Checkout
When you run a write workflow that opens a draft merge request, or when you
publish a saved run, you might see git-checkout-unverified. DocsFab could not
verify the checkout’s Git setup, and it stopped. A publication that fails with
this code saves the write.
Before the model starts, DocsFab raises this code when
git config --show-origin --list fails, prints more than
delivery.gitConfigurationListingMaxBytes, or prints something DocsFab cannot
read. At publication, DocsFab raises it for any of these conditions:
- Git is older than 2.9.5, or
git versionprints something DocsFab cannot read. - The remote’s URL no longer names the host, project, and transport that the publication plan names, or the remote has more than one URL.
- The configuration listing fails, for example because a configuration file is
malformed, prints more than
delivery.gitConfigurationListingMaxBytes, or does not parse.
The limit is 2 MiB by default, far above what a typical configuration prints. The message that stops a run before the model starts names the limit when the listing exceeds it. The check before the model starts and the publisher read the listing under the same limit, so a listing that passes the first passes the second.
DocsFab cannot verify a setting that has no value, such as a line that holds
only foo under [core]. Git reads such a setting as true. DocsFab refuses it
and reports git-checkout-unverified, not git-configuration-refused.
To find the cause, check each condition in the checkout:
To resolve this issue, upgrade Git, restore the remote’s URL, fix the
configuration file that git config reports as malformed, or give the setting a
value or remove it. If the listing is larger than the limit, remove what makes
it large, or raise DOCSFAB_DELIVERY_GIT_CONFIGURATION_LISTING_MAX_BYTES, up to
16 MiB. Then run the same command again. If DocsFab had already written the
change, retry publication of the saved run instead. The workflow does not run
again:
A retry that still cannot verify the checkout fails with
git-checkout-unverified again and keeps the publication retryable, even after
DocsFab committed. A publication that an earlier failure had already recovered
to patch-only cannot publish again. It reports this code with the next action
review-preserved-patch, so review the preserved patch instead.
After the fix, the run starts the model, or the retry opens the draft merge request, or either fails with a different typed code.
Live Agent Cannot Change a Page
When you ask the live agent to edit a page, you might see the following
message: DocsFab denied the requested tool path. It is outside this session's documentation scope.
A command can also fail with Operation not permitted on macOS or
Read-only file system on Linux. The live agent edits only documentation
paths: docs/, doc/, documentation/, and fern/ directories, root
README files, and the directories listed in documentationRoots in
.docsfab.json.
To resolve this issue, do one of the following:
- Move the pages under
docs/. - Enter
ywhen the live agent asks to allow edits in the page’s directory, and enteryagain to save the directory todocumentationRoots. Then commit.docsfab.json. - Add the directory to
documentationRootsin.docsfab.json, and commit the change.
If the live agent reports that it is read-only, start the session without
--read-only. For more information, refer to
Live Agent Reference in DocsFab.
Live Agent Commands Fail Because Command Isolation Is Unavailable
When the live agent runs an approved command on Linux, you might see the
following message: Documentation-only command isolation is unavailable. No command ran.
Workflow runs that need a repository check can stop with
required-check-unavailable and the reason linux-bubblewrap-unavailable.
DocsFab runs commands only inside an isolated sandbox. On Linux, the sandbox
uses Bubblewrap, which needs unprivileged user namespaces.
To resolve this issue, install Bubblewrap from your distribution, such as
sudo apt install bubblewrap, and confirm that the following command
succeeds:
If Bubblewrap is installed but the command fails, the host does not allow unprivileged user namespaces. On Ubuntu 24.04 and later, AppArmor restricts them by default. Ask your system administrator to allow user namespaces for Bubblewrap. Direct documentation edits keep working without command isolation.
Model Calls Fail or the Model Key Is Rejected
When a run makes its first model call, it can stop with
request-intent-model-unavailable, or a provider error such as HTTP 401 can
appear. If the key is wrong, docsfab why can still describe the failure as a
provider capacity problem.
To resolve this issue, first confirm that the key works with your model
provider, for example with the provider’s console or a request to its models
endpoint. A key can be rejected when it was copied incompletely or pasted twice.
Then run docsfab setup again and paste the key once at the hidden prompt. The
prompt does not display the key while you paste it.
If the provider accepts the key and calls still fail, the provider might be unavailable or rate-limited. Wait, and then start the run again.
Model Selection Is No Longer Supported
An older internal configuration can stop with composition-retired when its
model selection is no longer supported. The message names the reason and a
replacement. Follow the printed Next action to select that replacement, or
run docsfab setup in a terminal to choose another model.
DocsFab keeps the saved configuration until you explicitly choose a replacement. For setup choices, refer to Configure the Model.
A Composition Does Not Match the Host Configuration
If a live command fails with envelope code deployment-binding-mismatch,
the configured MODEL_BASE_URL or baseUrl setting cannot be parsed, or it
carries a user name, password, query, or fragment. Set it to a plain HTTPS URL,
then retry, and follow the printed Next action when it is more specific. An
endpoint other than the composition’s recorded origin does not stop the run:
it runs with a warning. When a docsfab run names a composition with
--composition <composition-id>, that composition is the run’s preset and the
host configuration’s settings apply on top of it. A provider route that differs
from the preset’s is replaced by the preset’s route, and a model ID that
differs runs as configured; DocsFab warns about each. Refer to
Change a Preset’s Settings.
No Model Profile or Model Key Is Configured
When you run docsfab run, docsfab do, or docsfab doctor --live, you
might see DocsFab found no loadable model profile,
provider-credentials-missing, or a message that names a missing key.
Commands that do not call a model, such as docsfab list and
docsfab test, work without a key.
The human docsfab run missing-profile error names the selected configuration
directory and its host.yaml and secrets.env paths. If you did not set
DOCSFAB_CONFIG_ROOT, the paths point to your default configuration directory.
The JSON error names the files without publishing host paths. DocsFab hides
credential-like text in local paths and does not print stored keys.
To resolve this issue, run docsfab setup in a terminal. Choose your model
provider and model, and enter the key at the hidden prompt. DocsFab stores the
key in the owner-only secrets.env file in its configuration directory. To
use a model profile that DocsFab installs, run
docsfab setup --profile <profile-id>, and use docsfab composition list to
see the available profile IDs. In a script, pass --provider and --model,
or --profile, and set the key in the environment variable that setup names.
Keep the following points in mind:
- DocsFab has no default model, so setup without a model choice stops with
setup-model-choice-required. - Each profile reads its key from one named variable. A key stored under
another name, such as
NVIDIA_API_KEYorNGC_API_KEY, is not used. - If a profile accepts two variable names and both are set, the run stops because the key source is ambiguous. Keep one of them.
- Do not put keys in
.docsfab.jsonor in the repository.
To check the result, run docsfab profile inspect. For more information,
refer to Install DocsFab.
Setup Cannot Update the Secrets File
Setup replaces secrets.env in one step through a temporary file, so a
reader never sees a partial file. A secrets.env.lock file in the same
directory serializes concurrent setup runs. Rerunning setup keeps every saved
key unless you enter a new value, and it does not rewrite an unchanged file.
Setup updates the model profile under profiles/, host.yaml, and
secrets.env as one configuration change. It checks inputs and acquires the
secrets lock before writing. Refused input leaves the previous model selection
and its key in place. If a later write fails, setup attempts to restore the
original files. Setup replaces files one at a time, so a program that reads
the configuration during a change can briefly see the new secrets.env with
the old host.yaml.
Before setup replaces a file, it keeps the original: a hard link where the
filesystem supports one, or a copy with the same permissions and timestamps
where it does not, such as on a FAT volume. If setup cannot keep a copy, for
example because the disk is full, it stops with setup-backup-failed, names
the file and the configuration root, and puts back anything it already
replaced. If a later write fails, setup moves the originals back with their
permissions and symbolic links. Before it moves an original back, setup checks
that the file still holds the bytes it wrote, with the same inode and change
time. A file that another writer replaced or edited in the meantime stays as
that writer left it.
If setup cannot put an original back, or leaves a file that another writer
changed, it stops with setup-commit-incomplete.
The message names each such path and where setup kept its original, as
<file>.setup-incomplete.<id>.bak. Setup never removes those kept originals.
Copy each one back over its path, or delete it if you do not need it, then
rerun setup. docsfab setup --migrate follows the same rules and keeps .env
in place until the split layout is complete. Setup does not undo a change that
a crash or a killed process interrupts.
When setup saves a key, it replaces only that key’s line and appends keys that
are new. Comments, other settings, and their formatting stay byte for byte.
Setup quotes a value when needed, so every saved value reads back exactly. A
value that does not fit on one line stops setup with
secrets-env-value-unrepresentable. Replacing a value that spans several
lines stops setup with secrets-env-line-unsupported. Both messages name the
key, never the value. In secrets.env and .env, a # starts a comment
only at the start of a value or after whitespace. Inside double quotes, \\
and \" are the only escapes.
If another setup holds the lock past the secrets.lockWaitMs bound, setup
stops with secrets-lock-wait-ms-bound and names the lock file. The
DOCSFAB_SECRETS_LOCK_WAIT_MS, DOCSFAB_SECRETS_LOCK_STALE_MS, and
DOCSFAB_SECRETS_LOCK_RETRY_MS variables can only lower those bounds.
The stale bound must stay below the wait bound so a waiter can recover an
abandoned lock. A lock whose owner still runs on this host is never taken
over, even when those variables are lowered. You can set these variables in
the environment, in the configuration root (secrets.env, or .env for the
legacy layout), or in the host limits file; docsfab doctor --limits reports
the same effective values the lock uses. In a configuration root file,
DocsFab reads only limit-override keys, with the same rules it uses to load
that file, so export lines, spaces around =, quoted values, and other
settings are accepted and ignored. Setup and live-agent check the lock
overrides before changing any file. An invalid value, or a stale bound at or
above the wait bound, stops with secrets-lock-override-invalid. The message
names each lock override and the file and line that set it, never its value.
docsfab live-agent prints the configuration root and secrets file in use.
docsfab doctor reports readiness without printing those paths.
Setup waits for a lock that a running process on the same host holds, however
long that process holds it. Setup checks that it still holds the lock before
it replaces each file. If another writer takes the lock first, setup stops with
secrets-env-lock-lost and moves back the files it already replaced. Setup
stops with secrets-env-lock-invalid when secrets.env.lock is not a regular
file, such as a broken symbolic link. Remove that path and rerun setup. On its
next write, setup removes the temporary copies and the kept originals that an
interrupted setup process left behind, except the .setup-incomplete. copies
described above. If secrets.env
is a symbolic link, setup replaces the link with a regular file and does not
write to the link target.
The Configuration Directory Is Rejected
When you run docsfab init, you might see the following message:
configuration-root-not-canonical. DocsFab requires its configuration
directory to be one absolute, normalized path that is not reached through a
symbolic link, and that only you can write to. On macOS, /tmp is a symbolic
link to /private/tmp, so a directory under /tmp is refused.
To resolve this issue, run the command that the Next action: line prints.
It creates the directory with owner-only permissions and sets
DOCSFAB_CONFIG_ROOT to its resolved path. Then preview docsfab init
again.
The Plan Writes Outside the Documentation Roots
When a create, update, or restructure run plans its changes, it can stop with
plan-outside-write-roots or plan-target-not-writable before anything is
written. The message names each path. A run writes only Markdown and MDX pages
inside the documentation write roots: the documentationRoots in
.docsfab.json, or docs/ and fern/ when none are set.
To resolve this issue, do one of the following:
- Name a target page inside the documentation roots.
- Add the directory to
documentationRootsin.docsfab.json, commit the change, and start a new run. - Change files that are not documentation pages, such as source code,
OpenAPI specifications, or
AGENTS.md, yourself.
If a create or update request names an output path that goes up a directory,
such as ../outside.md or docs/../src/x.md, the run stops with
proposal-scope-unsafe-target before it writes anything. Name the page with a
repository-relative path inside a documentation root, such as docs/guide.md,
and start a new run. If you have not chosen a page, ask DocsFab to create one
without naming a path, and answer its question about where to put it.
The Review Report Page Does Not Load
When review-documentation prints a Report: URL, such as
http://127.0.0.1:8787/reports/<run-id>/, the page might not load in your
browser. The report is served only while docsfab reports serve runs.
To resolve this issue, start the report server with the same state directory as the run, and keep it running while you read the report:
The server listens on 127.0.0.1:8787 by default. Use --bind 0.0.0.0
only when you intend to share the port.
WSL2 Storage or Command Isolation Fails
When you run DocsFab on Windows 11 with WSL2, an operation on DocsFab’s
private files might report an ownership or permission failure. An approved
live agent command might report live-command-wsl-interop-unavailable, or
report that documentation-only command isolation is unavailable. These
failures usually mean that Node.js or another tool is a Windows executable,
that DocsFab files are on a Windows drive, or that Bubblewrap cannot create
user namespaces.
To find the cause, run the following commands in the Ubuntu terminal:
To resolve this issue, use the Linux versions of Git, Node.js, npm, and
glab. Windows .exe tools are unavailable inside an approved DocsFab
command. Keep the repository, ~/.config/docsfab/, and DocsFab state in the
Linux file system, and keep their owner-only permissions when you move them.
Install Bubblewrap, and use a WSL2 host where unprivileged user namespaces
work. If live-command-wsl-interop-unavailable persists after you restart
your WSL session, remove any custom mounts or socket links for the Windows
bridge that you created outside DocsFab, and try again. Direct documentation
edits keep working without command isolation.
To confirm the fix, run docsfab test --json. For more information, refer to
Windows Installation Instructions.
Error Messages
Each failure prints a Docs: line and its own Next action: line. The
following table lists the codes that link to this page from the DocsFab Docs:
line.
Related Topics
The following pages provide related information: