iOfficeAI/OfficeCLI · error · CliException
file_locked
file_locked
Error message
{Path.GetFileName(file)} is currently opened by a resident process. Please run 'officecli close "{file}"' first. What it means
The target file is currently held open by the officecli resident server process (a long-lived handler that keeps the document loaded). Import/create refuse to proceed to avoid corrupting the resident's in-memory state. If the on-disk file is already gone it is treated as a stale resident and auto-closed; this error only fires when the file still exists and is genuinely locked.
Source
Thrown at src/officecli/CommandBuilder.Import.cs:178
file += ext;
}
// Check if the file is held by a resident process
var fullPath = Path.GetFullPath(file);
if (ResidentClient.TryConnect(fullPath, out _))
{
// Stale-resident recovery: if the on-disk file is gone (typical
// example-script pattern: os.remove(FILE) then `create`), the
// resident is pinning a path that no longer exists. Auto-close
// it and proceed — refusing here would force every example
// script to wrap `create` in a defensive `close`.
if (!File.Exists(fullPath))
{
ResidentClient.SendClose(fullPath);
}
else
{
throw new CliException($"{Path.GetFileName(file)} is currently opened by a resident process. Please run 'officecli close \"{file}\"' first.")
{
Code = "file_locked",
Suggestion = $"Run: officecli close \"{file}\""
};
}
}
// Refuse to silently overwrite an existing file unless --force is set.
// OpenXML SDK's Create truncates the target otherwise, which can destroy
// user data when an AI agent retries or mis-types the path.
if (File.Exists(fullPath) && !force)
{
throw new CliException($"File already exists: {file}. Use --force to overwrite.")
{
Code = "file_exists",
Suggestion = "Add --force flag or remove the file first."
};
}View on GitHub (pinned to 1ced45e900)
Solutions
- Close the resident: 'officecli close "<file>"', then retry.
- If the resident is stale or unreachable, restart the resident server.
- Structure scripts to close resident-held files before import/create.
Example fix
// before officecli import data.xlsx --file rows.csv # resident holds data.xlsx // after officecli close data.xlsx officecli import data.xlsx --file rows.csv
Defensive patterns
Strategy: validation
Validate before calling
if (ResidentClient.TryConnect(Path.GetFullPath(target), out _))
{
ResidentClient.SendClose(Path.GetFullPath(target));
// optionally wait briefly for release, then proceed
} Try / catch
// On CliException { Code = "file_locked" }: close the resident and retry once.
try { RunImport(target, src); }
catch (CliException e) when (e.Code == "file_locked") {
ResidentClient.SendClose(Path.GetFullPath(target));
RunImport(target, src);
} Prevention
- Always 'close' resident-held files before import/create in pipelines.
- Avoid mixing resident and one-shot commands on the same file in one script.
- Detect 'file_locked' and auto-close+retry once.
When it happens
Trigger: After a resident-mode command (e.g. an earlier 'view'/'set' with resident enabled) left the file open in the resident server, then running 'officecli import <same-file>' or 'create' over it.
Common situations: An agent session mixing resident and non-resident commands on the same file; a resident server left running from a prior session; forgetting to close after batch work.
Related errors
- -1
- ${r.stderr || r.stdout}
- Cannot read OLE source file '{srcPath}': the file is locked
- file_not_found
- unsupported_type
AI-assisted analysis of iOfficeAI/OfficeCLI@1ced45e900 (2026-08-13).
Data as JSON: /api/errors/316972a6bb8706e7.
Report an issue: GitHub.