Skip to content

codedeploy install/uninstall: TypeError (bytes vs str) crashes when agent service not found #10576

Description

@Adityaj0

Summary

aws deploy install / aws deploy uninstall (the on-premises CodeDeploy agent installer) crashes with an unhandled TypeError instead of gracefully handling the case where the codedeployagent/codedeploy-agent service does not exist yet — which is exactly the situation on a fresh host doing its first install.

Root cause

awscli/customizations/codedeploy/systems.py creates several subprocess.Popen(...) calls without text=True/universal_newlines=True:

process = subprocess.Popen(
    ['service', 'codedeploy-agent', 'stop'],
    stdout=subprocess.PIPE,
    stderr=subprocess.PIPE
)
(output, error) = process.communicate()
if process.returncode != 0 and params.not_found_msg not in error:
    raise RuntimeError(...)

Because text=True is omitted, process.communicate() returns bytes, but the code checks membership of a str literal (params.not_found_msg, or the not_found/"Running" literals in the Windows class) against that bytes object. In Python 3, "str" in b"bytes" raises TypeError: a bytes-like object is required, not 'str' — it does not evaluate to False.

Affected locations:

  • Windows.install (~L75): if process.returncode != 0 and not_found not in error:
  • Windows.install (~L108): if "Running" not in output:
  • Windows.uninstall (same pattern as install)
  • Linux._stop_agent (~L208, used by Ubuntu/RHEL install/uninstall): if process.returncode != 0 and params.not_found_msg not in error:

Reproduction

Verified by executing the real, unmodified Linux._stop_agent method against a stub service binary that reproduces the "service not registered yet" condition (exit code 1, stderr containing the expected "not found" message):

import sys
from awscli.customizations.codedeploy.systems import Linux

class Params(dict):
    def __getattr__(self, k):
        return self[k]

linux = Linux.__new__(Linux)
params = Params()
params['not_found_msg'] = 'codedeploy-agent: unrecognized service'

linux._stop_agent(params)

with a service script on PATH that does:

#!/bin/bash
echo "service: unrecognized service" 1>&2
exit 1

Result:

TypeError: a bytes-like object is required, not 'str'

instead of the intended graceful pass-through (or the documented RuntimeError when the failure is for a different reason).

Impact

This affects essentially every fresh aws deploy install and every aws deploy uninstall on Windows, Ubuntu, and RHEL on-premises instances — i.e. exactly the first-run scenario the not_found/not_found_msg check was written to tolerate. Instead of installing successfully or uninstalling cleanly, the command crashes with an unrelated TypeError traceback.

Suggested fix

Add text=True (or universal_newlines=True) to each subprocess.Popen(...) call in awscli/customizations/codedeploy/systems.py so communicate() returns str, matching what the existing string-membership checks assume.

Environment

Reviewed against the current aws-cli source. This is aws-cli-specific customization code (not vendored botocore).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions