microsoft/typescript-go · error
unsupported file extension: %s
Error message
unsupported file extension: %s
What it means
Returned by the project API file-update path when a newly opened/updated overlay file's extension maps to core.ScriptKindUnknown. The overlay's script kind is derived from the file name via GetScriptKindFromFileName, which only recognizes .js/.cjs/.mjs/.jsx/.ts/.cts/.mts/.tsx/.json (case-insensitive); anything else — no extension, .vue, .svelte, .txt — cannot be assigned a parser kind and the snapshot update is refused. Note this only applies to files not already in the overlay set; existing overlays reuse their recorded kind.
Source
Thrown at internal/project/api.go:56
// An error is returned if the file name does not have a recognized script extension.
// On success, the returned snapshot carries a single reference (the clone ref);
// the caller must call snapshot.Deref(s) when done.
func (s *Session) APIUpdateTemporary(ctx context.Context, baseSnapshot *Snapshot, uri lsproto.DocumentUri, newText string) (*Snapshot, error) {
path := uri.Path(baseSnapshot.UseCaseSensitiveFileNames())
overlays := maps.Clone(baseSnapshot.fs.overlays)
version := int32(0)
var fileChanges FileChangeSummary
existing := overlays[path]
var scriptKind core.ScriptKind
if existing != nil {
version = existing.Version() + 1
scriptKind = existing.Kind()
fileChanges.Changed.Add(uri)
} else {
scriptKind = core.GetScriptKindFromFileName(uri.FileName())
if scriptKind == core.ScriptKindUnknown {
return nil, fmt.Errorf("unsupported file extension: %s", uri.FileName())
}
fileChanges.Opened = uri
}
overlays[path] = newOverlay(uri.FileName(), newText, version, scriptKind)
newSnapshot := baseSnapshot.Clone(ctx, SnapshotChange{
fileChanges: fileChanges,
ResourceRequest: ResourceRequest{
Documents: []lsproto.DocumentUri{uri},
},
}, overlays, s)
return newSnapshot, nil
}
View on GitHub (pinned to 1bcfa18d79)
Solutions
- Only open/update files with .ts/.tsx/.mts/.cts/.js/.jsx/.mjs/.cjs/.json extensions
- Filter non-TS documents before forwarding them from an editor integration
- For framework files (.vue/.svelte), extract the script block into a virtual .ts/.js URI before handing it over
- Check the last suffix of the path client-side if uncertain
Example fix
// before
snap, err := proj.UpdateFile(ctx, uri "/src/Component.vue", text)
// after
if core.GetScriptKindFromFileName(name) == core.ScriptKindUnknown {
return fmt.Errorf("skip non-TS file: %s", name)
}
snap, err := proj.UpdateFile(ctx, uri, text) Defensive patterns
Strategy: type-guard
Type guard
func isSupportedScriptFile(name string) bool {
switch strings.ToLower(filepath.Ext(name)) {
case ".ts", ".tsx", ".mts", ".cts", ".js", ".jsx", ".mjs", ".cjs", ".json":
return true
}
return false
} Try / catch
snap, err := proj.UpdateFile(ctx, uri, text)
if err != nil {
if strings.Contains(err.Error(), "unsupported file extension") {
return snap, nil // not a script file; skip silently
}
return nil, err
} Prevention
- Filter documents to .ts/.tsx/.mts/.cts/.js/.jsx/.mjs/.cjs/.json before the API call
- For .vue/.svelte sources, project the script block into a virtual .ts/.js path
- Remember extension matching is case-insensitive on the last suffix
When it happens
Trigger: Calling the API open/update with a .svelte, .vue, .astro, .md, or extensionless file; paths with uppercase extensions are fine (ToLower applied) but double extensions like .d.json style oddities still route by last suffix; HTML entry files passed as documents.
Common situations: Embedding the language service into frameworks whose source files carry non-TS extensions; tooling that mirrors all editor open documents (including README/HTML) into the API; scripts passing paths without extensions.
Related errors
- Cannot run a temporary file update on an inactive snapshot
- Snapshot is disposed
- Cannot create directory: a file already exists at "/${segmen
- Invalid file path: "${path}"
- Bad line number. Line: ${line}, lineStarts.length: ${lineSta
AI-assisted analysis of microsoft/typescript-go@1bcfa18d79 (2026-08-16).
Data as JSON: /api/errors/3eda3f70d4ae808c.
Report an issue: GitHub.