# Buggy code
def get_task_specific_params(args, task_name):
    """Search args for parameters specific to task.
    Args:
        args: main-program args, a config.Params object
        task_name: (string)
    Returns:
        AllenNLP Params object of task-specific params.
    """

    def _get_task_attr(attr_name, default=None):
        return config.get_task_attr(args, task_name, attr_name, default)

    params = {}
    params["cls_type"] = _get_task_attr("classifier")
    params["d_hid"] = _get_task_attr("classifier_hid_dim")
    params["d_proj"] = _get_task_attr("d_proj")
    params["shared_pair_attn"] = args.shared_pair_attn
    if args.shared_pair_attn:
        params["attn"] = args.pair_attn
        params["d_hid_attn"] = args.d_hid_attn
        params["dropout"] = args.classifier_dropout
    else:
        params["attn"] = _get_task_attr("pair_attn")
        params["d_hid_attn"] = _get_task_attr("d_hid_attn")
        params["dropout"] = _get_task_attr("classifier_dropout")

    # Used for edge probing. Other tasks can safely ignore.
    params["cls_loss_fn"] = _get_task_attr("classifier_loss_fn")
    params["cls_span_pooling"] = _get_task_attr("classifier_span_pooling")
    params["edgeprobe_cnn_context"] = _get_task_attr("edgeprobe_cnn_context")

    # For NLI probing tasks, might want to use a classifier trained on
    # something else (typically 'mnli').
    cls_task_name = _get_task_attr("use_classifier")
    # default to this task
    params["use_classifier"] = cls_task_name or task_name

    return Params(params)


# Traceback (ValueError)
Traceback (most recent call last):
File "main.py", line 566, in <module>
main(sys.argv[1:])
File "main.py", line 534, in main
phase="target_train",
File "/Users/srbowman/jiant/src/trainer.py", line 594, in train
output_dict = self._forward(batch, task=task)
File "/Users/srbowman/jiant/src/trainer.py", line 1035, in _forward
model_out = self._model.forward(task, tensor_batch)
File "/Users/srbowman/jiant/src/models.py", line 830, in forward
out = self._span_forward(batch, task, predict)
File "/Users/srbowman/jiant/src/models.py", line 917, in _span_forward
out = module.forward(batch, sent_embs, sent_mask, task, predict)
File "/Users/srbowman/jiant/src/modules/span_modules.py", line 134, in forward
out["loss"] = self.compute_loss(logits, batch["labels"].squeeze(dim=1), task)
File "/Users/srbowman/jiant/src/modules/span_modules.py", line 184, in compute_loss
raise ValueError("Unsupported loss type '%s' " "for edge probing." % self.loss_type)
ValueError: Unsupported loss type '' for edge probing.
Traceback (most recent call last):
File "main.py", line 577, in <module>
raise e  # re-raise exception, in case debugger is attached.
File "main.py", line 566, in <module>
main(sys.argv[1:])
File "main.py", line 534, in main
phase="target_train",
File "/Users/srbowman/jiant/src/trainer.py", line 594, in train
output_dict = self._forward(batch, task=task)
File "/Users/srbowman/jiant/src/trainer.py", line 1035, in _forward
model_out = self._model.forward(task, tensor_batch)
File "/Users/srbowman/jiant/src/models.py", line 830, in forward
out = self._span_forward(batch, task, predict)
File "/Users/srbowman/jiant/src/models.py", line 917, in _span_forward
out = module.forward(batch, sent_embs, sent_mask, task, predict)
File "/Users/srbowman/jiant/src/modules/span_modules.py", line 134, in forward
out["loss"] = self.compute_loss(logits, batch["labels"].squeeze(dim=1), task)
File "/Users/srbowman/jiant/src/modules/span_modules.py", line 184, in compute_loss
raise ValueError("Unsupported loss type '%s' " "for edge probing." % self.loss_type)
ValueError: Unsupported loss type '' for edge probing.

# Fixed code
def get_task_specific_params(args, task_name):
    """Search args for parameters specific to task.
    Args:
        args: main-program args, a config.Params object
        task_name: (string)
    Returns:
        AllenNLP Params object of task-specific params.
    """

    def _get_task_attr(attr_name, default=None):
        return config.get_task_attr(args, task_name, attr_name, default)

    params = {}
    params["cls_type"] = _get_task_attr("classifier")
    params["d_hid"] = _get_task_attr("classifier_hid_dim")
    params["d_proj"] = _get_task_attr("d_proj")
    params["shared_pair_attn"] = args.shared_pair_attn
    if args.shared_pair_attn:
        params["attn"] = args.pair_attn
        params["d_hid_attn"] = args.d_hid_attn
        params["dropout"] = args.classifier_dropout
    else:
        params["attn"] = _get_task_attr("pair_attn")
        params["d_hid_attn"] = _get_task_attr("d_hid_attn")
        params["dropout"] = _get_task_attr("classifier_dropout")

    # Used for span/edge classification. Other tasks can safely ignore.
    params["cls_loss_fn"] = _get_task_attr("span_classifier_loss_fn")
    params["cls_span_pooling"] = _get_task_attr("classifier_span_pooling")
    params["edgeprobe_cnn_context"] = _get_task_attr("edgeprobe_cnn_context")

    # For NLI probing tasks, might want to use a classifier trained on
    # something else (typically 'mnli').
    cls_task_name = _get_task_attr("use_classifier")
    # default to this task
    params["use_classifier"] = cls_task_name or task_name

    return Params(params)