# Arguments

> Declare a Command's positional arguments, make them required or optional, accept many values, parse them as types, and ask for missing ones.

This guide covers a Command's arguments. You will learn how to:

- Declare arguments, required or optional
- Accept any number of values
- Parse an argument as a number, an address or your own type
- Ask for a missing argument on a terminal

## Overview

Arguments are the values that follow a Command's name without a flag, such as the name in `act make:controller posts`. A Command declares them in order, so help shows them, and Tinka checks them before `Run` starts: a missing required argument, or one more than the Command takes, is a usage error. A Command that declares no arguments takes none.

## Declare arguments

List the arguments in `Args`, in order. `Run` reads their values from `c.Args`:

```go
var importCommand = &cli.Command{
	Name:    "posts:import",
	Summary: "Import posts from a file",
	Args:    []cli.Arg{{Name: "file", Usage: "The file to import", Required: true}},
	Run: func(ctx context.Context, c *cli.Call) (cli.Result, error) {
		file := c.Args[0]
		…
	},
}
```

```text title="Output"
$ act posts:import
Error: missing argument <file>.
  Fix: Run `act posts:import --help` to see usage
```

::::options

:::option{name="Name" type="string"}
Names the argument in help and errors, such as `<file>`.
:::

:::option{name="Usage" type="string"}
Says what the argument is, for help.
:::

:::option{name="Required" type="bool"}
Makes the argument's absence a usage error.
:::

:::option{name="Variadic" type="bool"}
Takes every remaining value. Only the last argument can be variadic.
:::

:::option{name="Prompt" type="string"}
The question to ask for the argument when it's missing and a person can answer. See [Ask for missing arguments](#ask-for-missing-arguments).
:::

::::

## Make arguments optional

An argument without `Required` may be left out. Check `len(c.Args)` before reading it, or use `cmp.Or` for a default:

```go
		name := "world"
		if len(c.Args) > 0 {
			name = c.Args[0]
		}
```

Help shows an optional argument in brackets, such as `act greet [flags] [<name>]`.

## Accept many values

Make the last argument `Variadic` to take every remaining value. Combined with `Required`, it needs at least one:

```go
var tag = &cli.Command{
	Name: "posts:tag",
	Args: []cli.Arg{{Name: "tag", Required: true}, {Name: "posts", Variadic: true}},
	Run: func(ctx context.Context, c *cli.Call) (cli.Result, error) {
		tag, posts := c.Args[0], c.Args[1:]
		…
	},
}
```

```sh
act posts:tag go 12 17 31
```

## Parse arguments as types

`c.Arg[T]` returns an argument as a `T`: a `string`, an `int`, `int64`, `float64`, `bool` or `time.Duration`, or any type that parses itself from text by implementing `encoding.TextUnmarshaler`, such as `netip.Addr` or a type of your own. A value that doesn't parse is a usage error that names the argument, and an argument that wasn't given is the zero value:

```go
var ping = &cli.Command{
	Name: "ping",
	Args: []cli.Arg{{Name: "addr", Required: true}, {Name: "count"}},
	Run: func(ctx context.Context, c *cli.Call) (cli.Result, error) {
		addr, err := c.Arg[netip.Addr](0)
		if err != nil {
			return nil, err
		}
		count, err := c.Arg[int](1)
		if err != nil {
			return nil, err
		}
		count = cmp.Or(count, 4)
		…
	},
}
```

```text title="Output"
$ act ping 1.2.3
Error: invalid <addr> "1.2.3": ParseAddr("1.2.3"): IPv4 address too short.
  Fix: Run `act ping --help` to see usage
```

## Ask for missing arguments

Give a required argument a `Prompt`, and a person who leaves it out is asked for it instead of getting an error:

```go
	Args: []cli.Arg{{Name: "file", Required: true, Prompt: "Which file should be imported?"}},
```

```text title="Output"
$ act posts:import
? Which file should be imported?
```

The question is asked only when a person can answer: in a terminal, outside [Agent mode](../../reference/agent-mode.md), and without `--no-interaction`. Otherwise the missing argument stays a usage error, so scripts and agents never wait for input.

## Pass values that start with a dash

Arguments and [flags](flags.md) may come in any order. Everything after `--` is an argument, even when it starts with a dash:

```sh
act posts:import -- -draft-.json
```

See also: [Flags](flags.md), [Prompts](prompts.md), [Creating Commands](commands.md)
