aws / aws/aws-cli

aws configure set: UnboundLocalError when nested key is followed by a comment, blank line, or end of file

Open
#10,554 1 comment 0 reactions 1 assignee Claimed by @RyanFitzSimmonsAK View on GitHub
bug configure investigating p2
Dominant language
Python
Stars
17.3k
Forks
4.6k
Avg merge
1d 2h
Merged PRs (30d)
13

Description

### Describe the bug

`aws configure set` crashes with an internal `UnboundLocalError` when writing a nested (sub-attribute) value into a config file where the parent key is not immediately followed by another indented option line.

The error surfaces to the user as a bare Python message with no indication of what is wrong with their config:

```
aws: [ERROR]: cannot access local variable 'current_indent' where it is not associated with a value
```

The command exits `255` and the config file is left unmodified.

### Regression Issue

- [ ] Select this option if this issue appears to be a regression.

### Expected Behavior

`aws configure set default.s3.max_concurrent_requests 20` should add the nested value under the existing `s3 =` key and exit `0`.

### Current Behavior

The command aborts with `UnboundLocalError` and exit code `255`.

Traceback (with `--debug` stripped to the relevant frames):

```
File "awscli/customizations/configure/writer.py", line 113, in update_config
self._update_section_contents(contents, section_name, new_values)
File "awscli/customizations/configure/writer.py", line 210, in _update_section_contents
j = self._update_subattributes(
File "awscli/customizations/configure/writer.py", line 246, in _update_subattributes
starting_indent == current_indent
UnboundLocalError: cannot access local variable 'current_indent' where it is not associated with a value
```

### Reproduction Steps

Any of the following three config files reproduce it. All are valid and all parse correctly with `botocore`.

**1. Parent key followed by a comment**

```ini
[default]
region = us-east-1
s3 =
# tune these later
```

**2. Parent key is the last line in the file**

```ini
[default]
s3 =
```

**3. Parent key followed by a blank line**

```ini
[default]
s3 =

```

Then run:

```console
$ AWS_CONFIG_FILE=./config aws configure set default.s3.max_concurrent_requests 20

aws: [ERROR]: cannot access local variable 'current_indent' where it is not associated with a value
$ echo $?
255
```

### Possible Solution

In `ConfigFileWriter._update_subattributes`, `current_indent` is only assigned inside the `if match is not None:` branch, but it is read unconditionally a few lines later:

```python
def _update_subattributes(self, index, contents, values, starting_indent):
index += 1
for i in range(index, len(contents)):
line = contents[i]
match = self.OPTION_REGEX.search(line)
if match is not None:
current_indent = len(match.group(1)) - len(match.group(1).lstrip())
...
if (
starting_indent == current_indent # <-- may be unbound
or self.SECTION_REGEX.search(line) is not None
):
...
else:
if starting_indent != current_indent: # <-- may be unbound
self._insert_new_values(i, contents, values, ' ')
return i
```

Comment and blank lines do not match `OPTION_REGEX`, so if the first line after the parent key is one of those, `current_indent` is never bound. If the parent key is the last line of the file the `range()` is empty, so both `current_indent` and `i` are unbound when the `else:` clause runs.

Seeding `current_indent = None` and `i = index - 1` before the loop fixes all three cases and preserves existing behaviour: `None` never compares equal to `starting_indent`, which is exactly the "this line does not end the nested block" behaviour that a stale indent value produced for comments appearing later in a block.

I have a PR ready with a fix and regression tests for all three cases.

### CLI version used

aws-cli/2.36.23 (reproduced on `v2` at 4c331fc)

### Environment details (OS name and version, etc.)

macOS 15 (Darwin 25.2.0), Python 3.12

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.