Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

`--local` commands read a different state directory than `cf dev`, and local list commands return `[]`

Open
#224 0 comments 1 reaction 0 assignees View on GitHub

Maintainers usually reply within 1 day

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
52/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
typescript
Domain
backend, cli

Research direction

Start by tracing how cf dev chooses ./.cloudflare/state and how --local commands resolve their default and --persist-to paths; the issue does not name source files or tests. Then inspect the implementations behind kv namespaces list --local and d1 list --local, comparing their state discovery with the Local Explorer endpoints and the working key/raw commands. Done means local commands use the expected state directory and list the same namespace and database IDs, or report an explicit unsupported-state error instead of returning []. Compare behavior with related issue #22.

Written by the indexing model from the issue text.

Description

Summary of the issue

After cf dev, the --local API commands can't see the data the dev server wrote, and the local list commands can't help you find it.

  1. Different default state directories. In a cf init project, cf dev persists to ./.cloudflare/state. --local commands default to ~/.config/cloudflare/state (per --help), even when run from the project directory. So without --persist-to they read an empty store and return [] with exit 0, which looks like "no data" instead of "wrong store".
  2. Local list commands return [] even with the right state directory. With --persist-to ./.cloudflare/state, cf kv namespaces list --local and cf d1 list --local both return []. The running dev server's Local Explorer lists the namespace (CACHE-demo) and database (DB-demo), and cf kv keys list --namespace-id CACHE-demo / cf d1 raw DB-demo work once you know those IDs. The only way to find the IDs from the CLI is to guess the <BINDING>-<worker> pattern.
Command (after cf dev wrote one KV key and one D1 row) Result
cf kv keys list --namespace-id CACHE-demo --local []
cf kv keys list --namespace-id CACHE-demo --local --persist-to .cloudflare/state [{"name":"hits"}]
cf kv namespaces list --local --persist-to .cloudflare/state []
cf d1 list --local --persist-to .cloudflare/state []
GET /cdn-cgi/local/explorer/api/storage/kv/namespaces (dev server running) [{"id":"CACHE-demo","title":"CACHE"}]
GET /cdn-cgi/local/explorer/api/d1/database (dev server running) [{"name":"DB","uuid":"DB-demo",...}]
Expected behaviour
  • Inside a project, --local commands use the same state directory as cf dev (or at least say which directory they read).
  • kv namespaces list --local and d1 list --local list the namespaces and databases in that state, using the same IDs the Local Explorer and the other --local commands accept. If listing isn't supported in cold state, return an error instead of []. The README says "Commands with no local explorer equivalent return an error".
Version of cf used

1.0.0-beta.12

System information and package versions
System:
  OS: macOS 27.0
  CPU: (18) arm64 Apple M5 Pro
  Shell: 5.9 - /bin/zsh
Binaries:
  Node: 26.8.2
  npm: 11.19.1
npmPackages:
  @cloudflare/vite-plugin: beta => 2.0.0-beta.sha-52b0dc0e9
  cf: ^1.0.0-beta.12 => 1.0.0-beta.12
Reproduction (optional)
cf init demo --package-manager npm && cd demo

cloudflare.config.ts, env:

CACHE: bindings.kv({}),
DB: bindings.d1({}),

src/index.ts:

export default {
	async fetch(req, env) {
		const n = Number((await env.CACHE.get("hits")) ?? 0) + 1;
		await env.CACHE.put("hits", String(n));
		await env.DB.exec("CREATE TABLE IF NOT EXISTS visits (id INTEGER PRIMARY KEY, at TEXT)");
		await env.DB.prepare("INSERT INTO visits (at) VALUES (?)").bind(new Date().toISOString()).run();
		return new Response(String(n));
	},
} satisfies ExportedHandler<Env>;
cf dev            # then curl http://localhost:5173 once, then stop it
cf kv keys list --namespace-id CACHE-demo --local                              # []
cf kv keys list --namespace-id CACHE-demo --local --persist-to .cloudflare/state  # [{"name":"hits"}]
cf kv namespaces list --local --persist-to .cloudflare/state                   # []
cf d1 list --local --persist-to .cloudflare/state                              # []
Relevant error logs (optional)

None. Every command exits 0. Related: #22 notes that --local and wrangler dev also default to different directories.

Dominant language
TypeScript
Stars
853
Forks
42
Avg merge
17h 57m
Merged PRs (30d)
146

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from cloudflare/cf

All issues in cloudflare/cf

Similar issues

More TypeScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.