Skip to content

Azure Functions CLI (v5) Bug Bash

Manvir Kaur edited this page May 29, 2026 · 33 revisions

Quick Reference:

🚨 YOU NEED TO SET THE FOLLOWING ENVIRONMENT VARIABLES FOR THE BUG BASH 🚨

The install script should do this for you with the -BugBash | BUGBASH=true flag being passed, but this is just FYI

# bash / zsh
export FUNC_CLI_WORKLOADS_SOURCE="https://pkgs.dev.azure.com/azfunc/public/_packaging/pre-release/nuget/v3/index.json"
export FUNC_CLI_QUICKSTART_MANIFEST_URL="https://raw.githubusercontent.com/Azure/azure-functions-templates/dev/Functions.Templates/Template-Manifest/manifest.json"
export FUNC_CLI_WORKLOADS_PRERELEASE="true"

# PowerShell
$env:FUNC_CLI_WORKLOADS_SOURCE = "https://pkgs.dev.azure.com/azfunc/public/_packaging/pre-release/nuget/v3/index.json"
$env:FUNC_CLI_QUICKSTART_MANIFEST_URL = "https://raw.githubusercontent.com/Azure/azure-functions-templates/dev/Functions.Templates/Template-Manifest/manifest.json"
$env:FUNC_CLI_WORKLOADS_PRERELEASE = "true"

Welcome! This document walks you through installing the new func CLI (v5), poking at every command surface, and running an end-to-end "init → new → run → pack" flow for each supported stack (Go, Node, Python, .NET).

The v5 CLI is a ground-up rebuild on .NET 10 with a workload-based extensibility model. v4 is still the way to package and publish today, so the E2E flow uses v5 for init / new / run and v4 for func pack.

Scope. Test what's documented here. If you find something weird outside the scripted flows, even better, log it!


1. Prerequisites

Install whichever of these you need for the flows you plan to test:

Tool Why Notes
.NET 10 SDK dotnet stack See global.json for the exact pinned version.
Node.js 20+ node stack LTS is fine.
Python 3.11+ python stack A venv-capable install.
Go 1.22+ go stack Only needed if you're testing the Go flow.
PowerShell 7+ or bash/zsh Install scripts One of them; the installer supports both.

You'll also want a clean working directory you don't mind throwing away. Suggested:

mkdir -p ~/func-bug-bash && cd ~/func-bug-bash

2. Install the v5 CLI

The installer auto-detects OS / arch, downloads the latest 5.x release from GitHub, drops it in ~/.azure-functions, and adds that to PATH. It will also set the required environment variables for you.

PowerShell (Windows, macOS, Linux)

& ([scriptblock]::Create((irm https://aka.ms/func-cli/install.ps1))) -Source jviau/azure-functions-core-tools -Prerelease -BugBash

Bash (macOS, Linux)

curl -sSL https://aka.ms/func-cli/install.sh | PRERELEASE=true SOURCE=jviau/azure-functions-core-tools BUGBASH=true bash
source ~/.bashrc # or ~/.zshrc, depending on your shell

Verify

func --version            # prints just the version
func --verbose            # prints version + runtime + install details
func help                 # full command tree

REQUIRED VARIABLES

The install script should do this for you with the -BugBash | BUGBASH=true flag being passed, but this is just FYI

# bash / zsh
export FUNC_CLI_WORKLOADS_SOURCE="https://pkgs.dev.azure.com/azfunc/public/_packaging/pre-release/nuget/v3/index.json"
export FUNC_CLI_QUICKSTART_MANIFEST_URL="https://raw.githubusercontent.com/Azure/azure-functions-templates/dev/Functions.Templates/Template-Manifest/manifest.json"
export FUNC_CLI_WORKLOADS_PRERELEASE="true"

# PowerShell
$env:FUNC_CLI_WORKLOADS_SOURCE = "https://pkgs.dev.azure.com/azfunc/public/_packaging/pre-release/nuget/v3/index.json"
$env:FUNC_CLI_QUICKSTART_MANIFEST_URL = "https://raw.githubusercontent.com/Azure/azure-functions-templates/dev/Functions.Templates/Template-Manifest/manifest.json"
$env:FUNC_CLI_WORKLOADS_PRERELEASE = "true"

3. Commands to exercise

For every command, run it with no args, with --help, with a bad value, and with Ctrl+C mid-flight. We care about:

  • Help text is accurate and matches what the command actually does.
  • Errors are actionable: they tell you what to do next.
  • Ctrl+C exits cleanly (no stack trace, non-zero exit code).
  • Colors / icons render correctly. Try NO_COLOR=1 func ... and a non-TTY pipe (func help | cat).

Top-level

Command Try
func No args, should show help.
func help [command] func help, func help workload, func help bogus.
func --version / func --verbose Both forms.
func version Same output as --version.

Setup

func setup prepares the local machine: host, extension bundle, and (since 5.0.0) the matching stack workload for your project.

func setup --help
func setup                              # interactive, detects from local.settings.json
func setup --features node
func setup --features python,host
func setup --features python,node,go
func setup --features runtime
func setup --non-interactive --yes
func setup --profile <profile-name>

Profiles

func profile list
func profile show <profile>
func profile set <profile>

Workloads

The full lifecycle of installable language workloads and tooling.

func workload search
func workload search dotnet
func workload list                      # what's installed
func workload install <id>
func workload install ./path/to/local.nupkg
func workload install <id> --version <semver>
func workload install <id> --exact
func workload install <id> --force
func workload update <id>
func workload uninstall <id>
func workload prune                     # remove inactive side-by-side installs

Aliases to try as <id>: dotnet, node, python, go.

Edge cases worth pushing on:

  • Install something, then install the same alias again, expect "already installed" rather than a duplicate.
  • Install with --force after a successful install.
  • func workload uninstall on something not installed.
  • func workload install bogus-package (resolution failure).
  • func workload install <id> --source ./does-not-exist.

Init / New / Run

These are the project-level commands. They require a stack workload to be installed first (see §7).

func init --help
func new --help
func run --help                         # also aliased as `func start`

Path argument variations — each of these commands accepts an optional positional [path]. Test both forms:

# With an explicit path (created if it doesn't exist)
func init MyApp
func new MyApp --template "HTTP trigger" --name hello
func run MyApp

# Without a path (uses the current working directory)
mkdir MyApp && cd MyApp
func init
func new --template "HTTP trigger" --name hello
func run

Things to push on:

  • func init MyApp and func init in ./MyApp should produce identical layouts.
  • Relative (./MyApp), absolute (/tmp/MyApp or C:\temp\MyApp), and bare (MyApp) paths all work.
  • Path with spaces ("My App") is handled correctly.
  • Passing a path to func new / func run that wasn't initialized produces a clear error, not a stack trace.
  • func run MyApp and cd MyApp && func run boot the same project.

Quickstart

mkdir quickstart
func quickstart --help
func quickstart list                       # browse available templates
func quickstart list --stack python
func quickstart info <template-id>         # details for one template
func quickstart [path]                           # interactive, prompts for choices
func quickstart --template <template-id> ./my-app   # skip all prompts
func quickstart --stack python --resource http
func quickstart --iac bicep
func quickstart --search mcp
func quickstart --fetch git                # force git instead of http (default is git too)
func run <path to host.json>
cd [path]
azd up

Things to push on:

  • Run with no installed stack workload, expect a clear "install a stack first" hint.
  • --template with an unknown id errors clearly.
  • Scaffolding into a non-empty directory: expected behaviour vs --force.
  • Filters combine sanely (--stack, --resource, --iac, --search).
  • After scaffolding, the project should be runnable end-to-end (see §7).

4. Cross-cutting things to test

These apply to every command:

Area How to test
Cancellation Start a long-running command (func setup, func workload install ...), hit Ctrl+C. Expect a graceful exit (no stack trace, non-zero exit code).
Colors / themes Run with NO_COLOR=1. Pipe through cat. Both should produce readable, unstyled output.
Non-TTY Run any interactive prompt with stdin redirected from /dev/null, expect a clear "non-interactive, please pass --xyz" error, not a hang.
Telemetry opt-out Set FUNC_CLI_TELEMETRY_OPTOUT=1 (or the legacy FUNCTIONS_CORE_TOOLS_TELEMETRY_OPTOUT=1) and run any command. Nothing should change in the user-facing output, but telemetry should be off.
Help discoverability For every subcommand, --help describes every option, and func help <command> matches it.
Error text Errors should say what to do next. "Run func workload install node" is good; a bare exception message is a bug.

5. Output modes for func run

func run --output <mode> supports three modes. Test all three:

func run --output compact     # default: interactive TUI
func run --output plain       # line-based, for CI / non-TTY
func run --output json        # one JSON event per line

For json, validate with:

func run --output json | jq -c .   # every line parses as JSON

6. End-to-end flows per stack

The pattern for each stack is identical:

  1. Install the v5 stack workload.
  2. func init a new project.
  3. func new to add an HTTP trigger.
  4. func run to boot it locally and curl the trigger.

Open a fresh directory per stack so they don't tangle:

cd ~/func-bug-bash
mkdir node-app python-app dotnet-app go-app

6.1 Node

func workload install node

cd ~/func-bug-bash/node-app
func init --stack node --language javascript # try variations such as typescript, ts, js
func new --template "HTTP trigger" --name hello
func run

# In another shell:
curl http://localhost:7071/api/hello

Repeat with --language typescript in a sibling directory.

6.2 Python

func workload install python

cd ~/func-bug-bash/python-app
python -m venv .venv && source .venv/bin/activate
func init --stack python
func new --template "HTTP trigger" --name hello
func run

curl http://localhost:7071/api/hello

6.3 .NET

func workload install dotnet

cd ~/func-bug-bash/dotnet-app
func init --stack dotnet --language C#
func new --template "HTTP trigger" --name Hello
func run

curl http://localhost:7071/api/Hello

Also try --language F# in a sibling directory.

6.4 Go

func workload install go

cd ~/func-bug-bash/go-app
func init --stack go
func new --template "HTTP trigger" --name hello
func run

curl http://localhost:7071/api/hello

What to look for in each flow

  • func init creates a sensible project layout. Files match what a real developer would expect for that stack.
  • func init --force on a non-empty directory wipes it (except .git) and re-initializes cleanly.
  • func new lists templates when run without --template, and the chosen template scaffolds without errors.
  • func run boots the host, the trigger responds at http://localhost:7071/..., and Ctrl+C shuts it down cleanly.
  • func run --port 0 picks a free port; --port 7071 errors clearly if the port is taken.

7. Reporting bugs, issues, and suggestions

Please file everything as a GitHub issue. Bugs, papercuts, confusing output, missing features, doc gaps, naming nits, all of it. We'll triage incoming issues throughout the bug bash and fix as many as we can before the next drop, so the faster you file, the better the chance it lands.

File at https://github.com/Azure/azure-functions-core-tools/issues with the v5 label (and bug / enhancement / documentation as appropriate).

For each report, include:

  • func --verbose output (version + RID).
  • Exact command line and full output. For colored output, copy with NO_COLOR=1.
  • OS, shell, and (for stack-specific bugs) the runtime version of the stack.
  • Repro steps minimised to the smallest sequence that triggers the issue.
  • For crashes, attach the stack trace and, if possible, re-run with --verbose and include that output.

Don't sit on a "maybe it's just me" issue, file it. Duplicates are easy to close; missing reports are not.


8. Cleanup

When you're done:

# Uninstall installed workloads
func workload list                # see what's there
func workload uninstall dotnet
func workload uninstall node
func workload uninstall python
func workload uninstall go
func workload prune

# Remove the v5 install entirely
rm -rf ~/.azure-functions

# Clean up the bug-bash sandbox
rm -rf ~/func-bug-bash

If you edited your shell profile via the installer, also remove the
`export PATH="$HOME/.azure-functions:$PATH"` line it appended to
`~/.bashrc` / `~/.zshrc`.

---

Thanks for bug-bashing! 🐛🔨

# Troubleshooting

## Error: Package 'foo' is not a func CLI workload (missing package type 'FuncCliWorkload' in its .nuspec)

The workload source isn't set, so the CLI is resolving from nuget.org instead of the bug bash feed. Set it for your shell:

```Bash
# bash / zsh
export FUNC_CLI_WORKLOADS_SOURCE="https://pkgs.dev.azure.com/azfunc/public/_packaging/pre-release/nuget/v3/index.json"
export FUNC_CLI_WORKLOADS_PRERELEASE = "true"

# PowerShell
$env:FUNC_CLI_WORKLOADS_SOURCE = "https://pkgs.dev.azure.com/azfunc/public/_packaging/pre-release/nuget/v3/index.json"
$env:FUNC_CLI_WORKLOADS_PRERELEASE = "true"

Re-run the command. To make this stick across sessions, add the line to your shell profile (~/.zshrc, ~/.bashrc, or $PROFILE).

No quickstart templates found for the 'foo' stack

The quickstart manifest CDN isn't updated yet, point the CLI at the dev manifest:

# bash / zsh
export FUNC_CLI_QUICKSTART_MANIFEST_URL="https://raw.githubusercontent.com/Azure/azure-functions-templates/dev/Functions.Templates/Template-Manifest/manifest.json"

# PowerShell
$env:FUNC_CLI_QUICKSTART_MANIFEST_URL = "https://raw.githubusercontent.com/Azure/azure-functions-templates/dev/Functions.Templates/Template-Manifest/manifest.json"

Clear the cached manifest so the new URL is picked up:

# macOS / Linux
rm -rf ~/.azure-functions/quickstart

# Windows (PowerShell)
Remove-Item -Recurse -Force "$env:USERPROFILE\.azure-functions\quickstart"

Then re-run func quickstart.