sinelaw/fresh · error

no API declarations found in

Error message

no API declarations found in {} — start the editor once to write them

What it means

When collecting API declaration files from the declarations directory, none could be read, so the client bails telling you to start the editor once — the editor writes the .d.ts-style declaration files on first launch. Without them, script authoring/typechecking has no API surface to work from.

Solutions

  1. Start the Fresh editor once so it writes its API declaration files, then rerun the command.
  2. Check you are pointing at the correct declarations directory (the one printed in the message).
  3. If the editor was started but files are still missing, check editor logs for declaration write failures and fix permissions on the directory.
  4. Reinstall/repair Fresh if the editor repeatedly fails to emit declarations.

Example fix

# before
fresh --script-check myscript.js   # declarations never generated
# after
fresh main.rs          # first launch writes API declarations
fresh --script-check myscript.js
Defensive patterns

Strategy: fallback

Validate before calling

const fs = require('fs');
const path = require('path');
const dir = path.join(process.env.HOME, '.config/fresh/declarations');
const has = fs.existsSync(dir) && fs.readdirSync(dir).some(f => f.endsWith('.d.ts'));
if (!has) { console.error(`no declarations in ${dir}; start the editor once first`); process.exit(1); }

Try / catch

// bash
DECL_DIR="$HOME/.config/fresh/declarations"
if [ -z "$(ls "$DECL_DIR" 2>/dev/null)" ]; then
  echo 'starting editor once to generate API declarations...'
  fresh --headless-generate-declarations || fresh . && sleep 2
fi

Prevention

When it happens

Trigger: Running the declarations-consuming subcommand (e.g. script typecheck/authoring flow) before ever launching the editor, pointing at the wrong declarations directory, or the directory existing but all reads failing.

Common situations: Fresh install where the editor has never run; FRESH_CONFIG/HOME pointing elsewhere so the tool looks in the wrong dir; declarations cleaned by a cleanup script or never written due to an earlier startup failure.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


AI-assisted analysis of sinelaw/fresh@67894ca546 (2026-09-13). Data as JSON: /api/errors/f278be2a18223d6d. Report an issue: GitHub.

Appendix: source

Thrown at crates/fresh-editor/src/main.rs:4475

        }
    }
    entries
}

/// Where the API declarations live, and their contents.
fn read_api_declarations() -> AnyhowResult<Vec<(String, String)>> {
    let dir = fresh::config_io::DirectoryContext::from_system()?
        .config_dir
        .join("types");
    let mut out = Vec::new();
    for file in ["fresh.d.ts", "plugins.d.ts"] {
        let path = dir.join(file);
        if let Ok(text) = std::fs::read_to_string(&path) {
            out.push((file.to_string(), text));
        }
    }
    if out.is_empty() {
        anyhow::bail!(
            "no API declarations found in {} — start the editor once to write them",
            dir.display()
        );
    }
    Ok(out)
}

/// `fresh --cmd script api <query>` — find API members by name or description.
///
/// The alternative is grepping a 4000-line declaration file, where a search for
/// "split" returns every unrelated sense of the word. Matching the name first
/// and the prose second puts the verb you meant at the top, and printing each
/// hit with its doc comment means one call usually answers the question
/// outright.
fn script_api(query: &str, flags: &[&str]) -> AnyhowResult<()> {
    let json = flags.contains(&"--json");
    let needle = query.to_lowercase();
    let files = read_api_declarations()?;

View on GitHub (pinned to 67894ca546)