microsoft/typescript-go · error

project not found for open: %s

Error message

project not found for open: %s

What it means

Raised in project collection building when a config file name supplied via apiRequest.OpenProjects fails findOrCreateProject (returns nil), so the requested project cannot be created or located for opening. The API refuses to continue because the caller explicitly asked for a project that cannot be materialized — typically a nonexistent or unreadable tsconfig/jsconfig path.

Source

Thrown at internal/project/projectcollectionbuilder.go:175

					projectsToClose = make(map[tspath.Path]struct{})
				}
				projectsToClose[projectPath] = struct{}{}
			}
		}
	}

	if apiRequest.OpenProjects != nil {
		for configFileName := range apiRequest.OpenProjects.Keys() {
			configPath := b.toPath(configFileName)
			if entry := b.findOrCreateProject(configFileName, configPath, projectLoadKindCreate, logger); entry != nil {
				if b.apiState.openProjects == nil {
					b.apiState.openProjects = make(map[tspath.Path]int)
				}
				b.apiState.openProjects[configPath]++
				// A project re-opened in the same request shouldn't be closed.
				delete(projectsToClose, configPath)
			} else {
				return fmt.Errorf("project not found for open: %s", configFileName)
			}
		}
	}

	if apiRequest.CloseFiles != nil {
		for path := range apiRequest.CloseFiles.Keys() {
			// Ref-counted close mirroring projects above.
			if entry, ok := b.apiState.openFiles[path]; ok {
				if entry.refCount > 1 {
					entry.refCount--
					b.apiState.openFiles[path] = entry
				} else {
					delete(b.apiState.openFiles, path)
				}
			}
		}
	}

View on GitHub (pinned to 1bcfa18d79)

Solutions

  1. Verify each config file in OpenProjects exists and parses (valid JSON with expected fields) before sending the request
  2. Use absolute canonical paths matching the server's file-layout view
  3. Re-run project discovery and rebuild the open list rather than reusing a stale one

Example fix

// before
req.OpenProjects = collections.NewSet(tspath.Path("tsconfig.json"))

// after
abs, _ := filepath.Abs("tsconfig.json")
if _, err := os.Stat(abs); err != nil { return err }
req.OpenProjects = collections.NewSet(tspath.Path(abs))
Defensive patterns

Strategy: validation

Validate before calling

for cfg := range openProjects {
	abs, err := filepath.Abs(cfg)
	if err != nil { return err }
	if fi, err := os.Stat(abs); err != nil || fi.IsDir() {
		return fmt.Errorf("config not openable: %s", abs)
	}
	// optionally: json.Valid(mustRead(abs))
}

Try / catch

err := builder.Apply(apiRequest)
if err != nil && strings.Contains(err.Error(), "project not found for open") {
	// drop the bad entry, revalidate paths, retry once with the cleaned set
	apiRequest.OpenProjects.Remove(offender)
	return builder.Apply(apiRequest)
}

Prevention

When it happens

Trigger: OpenProjects containing a path to a tsconfig.json that does not exist on disk; config path that exists but cannot be loaded/parsed by the config loader; relative vs absolute path mismatch after b.toPath conversion; symlinked config whose target is missing.

Common situations: API clients passing workspace-relative config paths where absolute paths are expected; project moved/renamed between discovery and open; stale config list from a previous scan; containerized setups with different mount paths.

Related errors


AI-assisted analysis of microsoft/typescript-go@1bcfa18d79 (2026-08-16). Data as JSON: /api/errors/cf58193b474836cf. Report an issue: GitHub.